Given a singly linked list, determine if it is a palindrome.
Follow up:
Could you do it in O(n) time and O(1) space?
回文联表,这个与之前的回文数非常像,区别在于这里是处理链表,之前是处理数字,如果题目不限制时间与空间复杂度,那么可以考虑使用栈把前半个链表放入栈中之后再逐一比较后半段链表与栈顶元素即可,但是这里限制了空间复杂度,我们不能用栈来处理,但是我们可以用“快慢指针”的方法找到链表的中点,然后翻转后半段链表,之后再逐一比较即可,注意以下代码在链表节点为奇数或者偶数时都适用。从代码中我们可以看出,slow指针指向中点时,我们将slow之后的链表翻转,不含slow指向的节点,翻转的方法还是逐个节点进行
1 /**
2 * Definition for singly-linked list.
3 * struct ListNode {
4 * int val;
5 * ListNode *next;
6 * ListNode(int x) : val(x), next(NULL) {}
7 * };
8 */
9 class Solution {
10 public:
11 bool isPalindrome(ListNode* head) {
12 if (!head || !head->next)
13 return true;
14 ListNode *fast = head, *slow = head;
15 while (fast->next && fast->next->next)
16 {
17 slow = slow->next;
18 fast = fast->next->next;
19 }
20 //翻转后半个链表
21 ListNode *cur = slow->next;
22 while (cur && cur->next)
23 {
24 ListNode *tmp = cur->next;
25 cur->next = tmp->next;
26 tmp->next = slow->next;
27 slow->next = tmp;
28 }
29 fast = slow->next, slow = head;
30 while (fast)
31 {
32 if (slow->val != fast->val)
33 return false;
34 slow = slow->next;
35 fast = fast->next;
36 }
37 return true;
38 }
39 };
易错点:21行,一定是从slow->next开始处理