分析转自:http://www.cnblogs.com/CSGrandeur/p/3520937.html
设置两个指针slow和fast,从head开始,slow一次一步,fast一次两步,如果fast能再次追上slow则有圈。
设slow走了n步,则fast走了2*n步,设圈长度m,圈起点到head距离为k,相遇位置距离圈起点为t,则有:
n = k + t + pm; (1)
2*n = k + t + qm;(2)
这里p和q是任意整数。(不过fast速度是slow二倍,则肯定在一圈内追上,p就是0了)
2 * (1) - (2) 得k = lm - t;(l = q - 2 * p)
即 k 的长度是若干圈少了 t 的长度。
因此这时候,一个指针从head开始,另一个从相遇位置开始,都每次只走一步,当从head开始的指针走到圈开始位置时,两指针刚好相遇。
/*
* Solution.cpp
*
* Created on: 2014年4月9日
* Author: William
*/
#include <iostream>
using namespace std;
// 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) {
ListNode* pfast = head;
ListNode* pslow = head;
do { // Elegant, compared with Linked List Cycle done by me.
if (pfast != NULL)
pfast = pfast->next;
if (pfast != NULL)
pfast = pfast->next;
if (pfast == NULL)
return pfast;
pslow = pslow->next;
} while (pfast != pslow);
pfast = head;
while (pfast != pslow) {
pfast = pfast->next;
pslow = pslow->next;
}
return pfast;
}
};