思路:回文链表就是链表两边关于中间对称,那如果对称就是回文链表了,想要判断两边是否对称就要对两边一一比较,所以第一件事就是要找到中间结点,如何确定中间结点的位置?快慢指针呀!快指针每次走两步,慢指针每次走一步,当快指针都到链表最后的时候,慢指针走到中间结点。如何比较呢,因为是关于中心对称,所以前面的从左往右和后面的从右往左是一样的,那我们可以就可以将后面的链表逆序,然后得到后面链表逆序之后的首结点,就可以和前面的链表开始比较了。还有关于链表结点个数是奇还是偶的问题,如果是奇数,中间结点不比较,如果是偶数则全部比较,那我们怎样区分呢?其实将中间那个结点放在前面就行,当后面的链表为空的时候我们就不判断了,这样的话,如果是奇数,前面最后一个结点就不会参与比较了。
关于快慢指针,给大家来个图解吧!
奇数情况:
这时候fast不满足条件fast->next!=NULL&&fast->next->next!=NULL,退出快慢指针的移动,慢指针就移动到了中间。
偶数情况:
这个时候,fast不满足条件fast->next!=NULL&&fast->next->next!=NULL,退出快慢指针的移动,慢指针就移动到了前面的结尾。
代码实现C++:
bool isPalindrome(ListNode* head) {
if(head==NULL||head->next==NULL) return true;
ListNode *fast=head,*slow=head;
while(fast->next!=NULL&&fast->next->next!=NULL){
fast=fast->next->next;
slow=slow->next;
}
ListNode * newhead=reverse(slow->next);
while(newhead!=NULL){
if(newhead->val!=head->val){
return false;
}
newhead=newhead->next;
head=head->next;
}
return true;
}
ListNode *reverse(ListNode *newhead){
ListNode *p=newhead->next,*s=newhead,*q=newhead;
newhead->next=NULL;
while(p){
s=p;
p=p->next;
s->next=newhead;
newhead=s;
}
return newhead;
}