快慢指针找中点,反转后半段,与前半段比较,O(n) O(1)。
OJ: leetcodecn
题目 ID: palindrome-linked-list
难度:入门
标签:链表双指针栈cpppython
日期: 2026-07-28 22:05
题意
判断单链表是否为回文。
思路
数组存值再双指针 O(n) 空间。优化:快慢指针找到中间节点,反转后半段,逐节点比较。
代码
cpp
/**
* Author by Rainboy
*/
// main.cpp:快慢指针找中点,反转后半段,比较。
#include <bits/stdc++.h>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};
class Solution {
public:
bool isPalindrome(ListNode *head) {
if (!head || !head->next)
return true;
auto slow = head, fast = head;
while (fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
auto mid = slow->next;
slow->next = nullptr;
ListNode *prev = nullptr;
while (mid) {
auto nxt = mid->next;
mid->next = prev;
prev = mid;
mid = nxt;
}
auto a = head, b = prev;
while (b) {
if (a->val != b->val)
return false;
a = a->next;
b = b->next;
}
return true;
}
};
ListNode *build(istream &in, int n) {
if (!n)
return nullptr;
auto head = new ListNode(0), cur = head;
for (int i = 0, v; i < n; i++) {
in >> v;
cur->next = new ListNode(v);
cur = cur->next;
}
return head->next;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
auto head = build(cin, n);
cout << Solution().isPalindrome(head) << '\n';
return 0;
}python
#!/usr/bin/env python3
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def isPalindrome(self, head: ListNode) -> bool:
if not head or not head.next:
return True
slow = fast = head
while fast.next and fast.next.next:
slow = slow.next
fast = fast.next.next
mid = slow.next
slow.next = None
prev = None
while mid:
nxt = mid.next
mid.next = prev
prev = mid
mid = nxt
a, b = head, prev
while b:
if a.val != b.val:
return False
a, b = a.next, b.next
return True
def build(arr):
dummy = cur = ListNode(0)
for v in arr:
cur.next = ListNode(v)
cur = cur.next
return dummy.next
def main() -> None:
n = int(input())
a = list(map(int, input().split()))
head = build(a)
print(Solution().isPalindrome(head))
if __name__ == "__main__":
main()复杂度
- 时间复杂度:O(n)。
- 空间复杂度:O(1)。
总结
链表中点 + 反转是回文判断的标准做法。注意奇偶长度下中点的定位。