链表中环的入口结点
引例:给定一个链表,若其中包含环,则输出环的入口节点。若其中不包含环,则输出null。
给定如上所示的链表:
[1, 2, 3, 4, 5, 6]
2
注意,这里的2表示编号是2的节点,节点编号从0开始。所以编号是2的节点就是val等于3的节点。
则输出环的入口节点3.
本题所用到的方法是快慢指针扫描。
|
j走过的路径Sj = x + (y + z)*n + y;
i走过的路径Si = x + y;
由速度可知,二者的路径关系为Sj = 2 * Si;
即x + (y + z)*n + y = 2 * (x + y),整理得
x = (n - 1)(y + z) + z;
由于n是任意整数,不妨设为1,则x = z;
由此可知,j节点在c点再往前走x个长度即可到达b点。
为了节省内存,我们让i重新指向头结点,i和j同时往前以相同速度移动,当两者再次相遇时就找到了答案。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *entryNodeOfLoop(ListNode *head) {
auto i = head, j = head;//i是慢的, j是快的
while(i && j){
i = i -> next;
j = j -> next;
if(!j) return NULL;
j = j -> next;
if(i == j){
i = head;
while( i != j){
i = i -> next;
j = j -> next;
}
return i;
}
}
return NULL;
}
};