题目
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
由定理得知:一个慢指针(每次走一步),一个快指针(每次走两步),如果该链表有环的情况下则慢指针和快指针会最终在环中相遇。
该定理可以通过数学归纳法证明:
慢指针和快指针之间相差的步数为1的时候,两个指针相差一步,如
此时继续往后走,慢指针前进一步,快指针前进两步,两者相遇。
慢指针和快指针之间相差的步数为2的时候,两个指针相差两步,此时继续往后走,慢指针前进一步,快指针前进两步,两者之间相差一步,转化为第一种情况
慢指针和快指针之间相差的步数n步时,两个指针相差n步,继续往后走,慢指针前进一步,快指针前进两步,两者之间相差N-1步。因此返回慢指针和快指针之间相差的步数为n-1的情况。
以此类推最终慢指针会和快指针相遇。
假设两指针在5节点相遇
设1节点到4节点距离为x,4到5为y,5到4为z。
慢指针行走距离为s,快指针为f,由题意2×s=f。
s=x-1+n(z+y)+y, f=x-2+N(z+y)+y。已知当fast指针比slow指针走多一圈时相遇,所以N=n+1;
n为slow在环里走的圈数,N为fast在环里走的圈数。所以综上所有条件得出x=z;
所以令p指针和slow指针再走x距离,便是环的入口。
public class Solution {
public ListNode EntryNodeOfLoop(ListNode head)
{
if(head==null||head.next==null) return null;
ListNode slow=head.next;
ListNode fast=head.next.next;
ListNode p=head;
while(slow!=fast){
slow=slow.next;
fast=fast.next.next;
}
while(p!=slow){
p=p.next;
slow=slow.next;
}
return p;
}
}
来源:CSDN
作者:jcjcjcjiangcheng
链接:https://blog.csdn.net/jcjcjcjiangcheng/article/details/103964624