LeetCode 234.回文链表(快慢指针+反转单链表)

题目描述:来自LeetCode

LeetCode 234.回文链表(快慢指针+反转单链表)

 思路:回文链表就是链表两边关于中间对称,那如果对称就是回文链表了,想要判断两边是否对称就要对两边一一比较,所以第一件事就是要找到中间结点,如何确定中间结点的位置?快慢指针呀!快指针每次走两步,慢指针每次走一步,当快指针都到链表最后的时候,慢指针走到中间结点。如何比较呢,因为是关于中心对称,所以前面的从左往右和后面的从右往左是一样的,那我们可以就可以将后面的链表逆序,然后得到后面链表逆序之后的首结点,就可以和前面的链表开始比较了。还有关于链表结点个数是奇还是偶的问题,如果是奇数,中间结点不比较,如果是偶数则全部比较,那我们怎样区分呢?其实将中间那个结点放在前面就行,当后面的链表为空的时候我们就不判断了,这样的话,如果是奇数,前面最后一个结点就不会参与比较了。

关于快慢指针,给大家来个图解吧!

奇数情况:

LeetCode 234.回文链表(快慢指针+反转单链表)

LeetCode 234.回文链表(快慢指针+反转单链表) 

LeetCode 234.回文链表(快慢指针+反转单链表) 

这时候fast不满足条件fast->next!=NULL&&fast->next->next!=NULL,退出快慢指针的移动,慢指针就移动到了中间。 

偶数情况:

LeetCode 234.回文链表(快慢指针+反转单链表)

LeetCode 234.回文链表(快慢指针+反转单链表) 

LeetCode 234.回文链表(快慢指针+反转单链表) 

这个时候,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;
    }

上一篇:双指针:leetcode142(中等)——环形链表2


下一篇:【LeetCode】—— 寻找重复数