Problem Description
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?
Problem Solution
Note: 假设循环结点与头结点之间路径长度为k,链表结点长度为n
1. 定义两个指针同时遍历链表,一个步阶为1,另一个步阶为2
2. 两指针相遇时应满足的条件:
1) 2p1=p2 (p1: 步阶为1指针所走结点路径长度,p2:步阶为2指针所走结点路径长度)
2) p2-p1 = (n - k)的倍数
由两式可推导得到:p1 = (n - k) 的倍数。
3. 第一次相遇是在步阶为1指针走了 n - k 步之后,这时,让步阶为1指针回到头结点的位置,步阶为2结点保持在相遇的结点,它们距离循环结点的距离都为 k ,然后以步阶为1进度遍历链表,再次相遇点即为循环结点位置。
/** * 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 || head->next==NULL) return NULL; ListNode *p,*q; p=q=head; while(p && p->next) { q=q->next; p=p->next->next; if(p==q) break; } if(p==NULL || p->next==NULL) return NULL; q=head; while(q!=p) { q=q->next; p=p->next; } return p; } };