题目:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
链接:https://www.nowcoder.com/questionTerminal/253d2c59ec3e4bc68da16833f79a38e4
来源:牛客网
思路:第一步,找环中的相汇点。分别用fast,slow指向链表头部,fast每次走2步,slow每次走1步,知道fast==slow找到在环中的相汇点。
第二步,找环的入口。当fast==slow时,fast所经过的节点数为2x,slow所经过的节点数为x。设环中有n个节点,fast比slow多走一圈有2x=n+x,n=x,可以看出slow实际走了一个环的步数,再定义一个指针p指向链表头部,slow位置不变,slow、p每次走一步直到p==slow,此时的p为环的入口。
(相遇问题:举个例子,A和B同时从一条小道跑入操场,A的速度比B快,肯定会在操场跑到里超过B,超过的瞬间它们俩相遇了,此时A已经B多跑了一圈(环比较小的时候,可能多跑很多圈才会相遇。)
package offer;
public class Solution23 {
public ListNode EntryNodeOfLoop(ListNode pHead) {
if (pHead == null)
return null;
ListNode fast = pHead;
ListNode slow = pHead;
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) { // fast和slow相遇了,说明链表中有环
ListNode p = pHead; // 再定义一个节点=头节点
while (p != slow) {
p = p.next;
slow = slow.next;
}
return p; // p与slow相遇时,返回p,为环入口。
}
}
return null;
}
}