题目描述
一个链表中包含环,请找出该链表的环的入口结点。
分析:此题说明了单链表中一定有环,且只有一个环,一般做法都是用快慢指针来进行跑,由于有环就不去判断是否有环
慢指针速度为1,块指针速度为2,第一次相遇后停止,让慢指针回到头,再次都以速度1开始跑,再次相遇的地点即为链表的环的入口点。
数学证明公式如下:
第一次相遇时:
慢指针走过的路程S1 = 非环部分长度 + 弧A长
快指针走过的路程S2 = 非环部分长度 + n * 环长 + 弧A长
S1 * 2 = S2,可得 非环部分长度 = n * 环长 - 弧A长
第二次相遇时:
S1 = 非环部分长度
S2 = 非环部分长度 + n * 环长 + 弧A长+非环部分长度
=非环部分长度 + n * 环长 + 弧A长+( n * 环长 - 弧A长)
= 非环部分长度 + m* 环长
所以代码如下:(没有去判断是否有环)
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ListNode EntryNodeOfLoop(ListNode pHead)
{
//题目说了一定有环,那就不去判断是否有环了
if(pHead==null||pHead.next==null) return null;
ListNode slow=pHead,fast=pHead;
while(fast.next!=null){
slow=slow.next;
fast=fast.next.next;
if(slow==fast){//第一次相遇
break;
}
}
//再来第二次相遇
slow=pHead;
while(slow!=fast){
slow=slow.next;
fast=fast.next;
}
return slow;
}
}