解题思路:
1,单向链表就只能从前找到后,不能反向迭代。
2,回文的特点,就是要从两边迭代到中间。
3,综合上述两个特点,可以想到把链表后半部分翻转一下(题目没说不能破坏原有结构),然后从链表的开头和中间开始,比较对应node的value
1,起始条件:lenList, curTail指向链表结尾,curMid指向链表中间,将链表后半部分翻转
2,不变式:比较curHeader++ 与 curMid++ 的value
3,结束条件:出现一次比较的结果不等,结束,返回false。或者链表curMid指向结尾NULL,结束,返回true
4,临界条件:链表为NULL,链表长度为1,这两种情况,均返回true
如何将链表翻转?
1,起始条件:p指向链表头部,t一直指向链表最初状态的那个尾部节点,q指向t->next
2,不变式:temp = p, p = temp.next, t->next = temp, temp->next = q, q = t->next
3,结束条件:p == t时,翻转结束
4,临界条件:链表为NULL或者链表长度为1,
// 编译错误
1,Line 27: ‘header’ was not declared in this scope
2,Line 48: request for member ‘val’ in ‘curHeaderStart’, which is of pointer type ‘ListNode*’ (maybe you meant to use ‘->’ ?)
// Wrong answer
1,链表为NULL或者长度为1时,都要返回true
2,后半部分 链表 reverse的算法有问题
a,链表的reverse需要三个游标,指向头的head,指向尾的t(改指针整个过程保持不变),指向t->next的q
b,每一次将head插入到 节点 t 和节点 q之间,更新head和q,t保持不变
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
if (head == NULL){
return true;
}
// find length of list
int lenList = 1;
ListNode* cursor = head;
while (cursor->next != NULL){
cursor = cursor->next;
lenList ++;
}
if (lenList == 1){
return true;
}
// get pointer to tail of list
ListNode* curTail = cursor;
// get pointer to middle of list
int midIndex = lenList/2 + lenList % 2 - 1;
ListNode* curMid = head;
while (midIndex != 0){
curMid = curMid->next;
midIndex --;
}
// reverse the last half of list
ListNode * mutableTail = curTail->next; // point to tail->next always
ListNode * temp = NULL; // point to curMid->next always
while (curMid->next != curTail){
temp = curMid->next;
curMid->next = temp->next;
curTail->next = temp;
temp->next = mutableTail;
mutableTail = curTail->next;
}
ListNode * curHeaderStart = head;
ListNode * curMidStart = curMid->next;
while (curMidStart != NULL){
if (curHeaderStart->val != curMidStart->val)
return false;
curHeaderStart = curHeaderStart->next;
curMidStart = curMidStart->next;
}
return true;
}
};