题解 | #链表中环的入口结点#
思路: 参照判断链表有环问题,我们可以知道当fast与slow首次相遇时,slow向后遍历到环的入口的距离与链表入口与环的入口的距离是相等的,所以,我们利用这个规律,在二者相遇时,定义一个临时指针于链表入口,让快慢指针继续移动,当慢指针与临时指针相遇时,该节点便是环的入口。 注意一种特殊情况,就是快慢指针相遇于环的入口,此时链表的入口与环的入口重合,需要在给临时指针赋值时检查此时慢指针是否与赋值后的临时指针相同(当然也可以直接判断是否与pHead相同)
代码:
/*
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 fast = pHead;
ListNode slow = pHead;
//定义临时指针
ListNode temp = null;
//定义标记保证是快慢指针首次到达
boolean flag = true;
//遍历链表,如果快慢指针指向了同一个结点,那么证明有环
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow&&flag) {
// 关闭标记
flag = false;
// 为临时指针赋值
temp = pHead;
// 判断环入口是否与链表路口重合
if(temp==slow){
return pHead;
}
// 跳过后面的执行
continue;
}
if(temp != null){
temp = temp.next;
if(temp == slow){
return slow;
}
}
}
return null;
}
}