链表-leetcode 142 Linked List Cycle II

来源:互联网 发布:aceplayer mac 编辑:程序博客网 时间:2024/06/08 15:18

原题链接:Linked List Cycle II

如果没有follow up 这道题会非常简单,也非常容易想到,代码如下:

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode *detectCycle(ListNode *head) {        /*            遍历链表,辅助set,如果遍历到的节点存在set中,说明循环开始了,返回,否则将节点插入到set中。否则直至遍历完,返回NULL;            Time Complexity:O(N)            Space Complexity:O(N)        */        if(!head || !head->next)return NULL;        set<ListNode*>liset;        while(head){            if(liset.find(head)!=liset.end())return head;            else{                liset.insert(head);                head=head->next;            }        }        return NULL;    }};

但是有了follow up的限制之后,不允许使用额外的空间,就需要点技巧了。有这么个方法:使用快慢指针,当快慢指针第一次相遇之后,将慢指针移动回头结点,然后以慢指针的速度移动快慢指针,再次相遇就是环初始节点。证明其实也很简单,可以参考(出处)
证明

明白了思路,代码就很简单了,如下

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode *detectCycle(ListNode *head) {        /*            使用快慢指针,如果存在环,当快慢指针第一次相遇,将慢指针移回头结点,在以同样的速度移动快慢指针,再次相遇即是环初始节点            Time Complexity:O(2a+b) (a:头结点到环初始节点距离,b:环初始节点到相遇节点的距离)        */        if(!head || !head->next)return NULL;        ListNode* slow=head->next,*fast=head->next->next;        while(fast && fast->next){            if(fast==slow){                slow=head;                while(true){                    if(slow==fast)return slow;                    slow=slow->next;                    fast=fast->next;                }            }            slow=slow->next;            fast=fast->next->next;        }        return NULL;    }};