题目链接:
https://leetcode.com/problems/linked-list-cycle-ii/
题意:
给定链表,求是否存在环,如果存在,求出环的入口。
分析:
可以用mapmap维护。
更优的话,引用Discuss中的大神的方法——
设一个slowslow和fastfast指针,初始在头结点,slowslow每次跳一个,fastfast每次跳两个。
如果存在环,那么最终fastfast和slowslow肯定会相遇,设相遇除结点为meetingmeeting,环的入口结点为entryentry。
设L1L1是headhead到entryentry距离,L2L2是entryentry到meetingmeeting的距离,CC是环的长度,相遇时fastfast指针在cycle里已经走过nn圈。
由于fastfast走的路程是slowslow的两倍,因此有2×(L1+L2)=L1+L2+n×C2×(L1+L2)=L1+L2+n×C,整理后得L1+L2=CL1+L2=C,也就是说从meetingmeeting出发回到entryentry经过的距离等于从headhead走到entryentry的距离。
http://blog.csdn.net/kenden23/article/details/13871699
同样,对于Find the duplicate number,可以将下标访问看成指针的跳转,将问题转化为求环形链表中是否存在小环。
/**
* 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) {
if(head == NULL) return head;
ListNode* slow = head;
ListNode* fast = head;
ListNode* entry = head;
while(fast->next != NULL && fast->next->next != NULL){
slow = slow->next;
fast = fast->next->next;
if(slow == fast){
while(slow != entry){
slow = slow->next;
entry = entry->next;
}
return entry;
}
}
return NULL;
}
};