题目描述:
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
解法:
image.png
设快慢两个指针分别从头节点开始走,快指针每次走两步,慢指针每次走一步
假设黑色路段长为x,蓝色路段长为a,环的总长度(蓝色+橙色)为c,走到相遇点时
快指针走过的路程 = x+mc+a(m:快指针在环中走的圈数)
慢指针走过的路程 = x+nc+a(n:慢指针在环中走的圈数)
推导公式:
2(x+nc+a) = x+mc+a
可得:x=c(n-2m+1)+c-a
得出结论:当快慢指针走到相遇点时,将其中一个指针从头节点开始走,另一个指针从相遇点开始走(走的速度一致),最终在环入口点相遇
public class Solution {
public ListNode EntryNodeOfLoop(ListNode pHead)
{
ListNode fast = pHead;
ListNode slow = pHead;
while(fast!=null && fast.next!=null){
fast = fast.next.next;
slow = slow.next;
if(fast==slow) break;
}
//如果fast为空,或者fast下一个节点为空,代表该链表没有环,返回null
if(fast==null || fast.next==null) return null;
//将slow设为从头节点开始走,fast从相遇点开始走,走的速度一致,当fast和slow相遇时即为环的入口节点
slow = pHead;
while(fast!=slow){
fast = fast.next;
slow = slow.next;
}
return slow;
}
}