Given a linked list, return the node where the cycle begins. If there is no cycle, return null
.
Follow up:
Can you solve it without using extra space?
这道题目可以用歪理来做,即遍历点,凡是已经遍历过的点就用一个特殊数标记,当遍历点数值为特殊值时,此点即为链表成环的起点。可以使用一个少见的特殊值,-2147483648(这个数值应该很少见吧。。。)当然这种方法会改变链表的value值,应该是不可取的。
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
while( head != NULL && head -> val != -2147483648 ) {
head -> val = -2147483648;
head = head -> next;
}
if( head == NULL ) return NULL;
else return head;
}
};
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *p1 = head,*p2 = head;
do{
if( p1 == NULL || p2 == NULL ) return NULL;
p1 = p1 -> next;
if( p2 -> next == NULL ) return NULL;
else
p2 = p2 -> next -> next;
}while( p1 != p2 );
p1 = head;
while( p1 != p2 ) {
p1 = p1 -> next;
p2 = p2 -> next;
}
return p1;
}
如图,若存在cycle,则head为A,cycle起点为B,取两指针p1,p2,p1每次走一步,p2每次走两步,若相遇在C点
则有 2×(a + n(b + c) + b) == a + b + m(b+c)
即a = (m - n)×(b + c) - b
= (m - n - 1) + c
此时再将p1设置为head,p1,p2同时同速走p1走完a路程时候p2正好走完整数圈+c路程两指针相遇在B点即起点上