方法1: hash,记录第一次出现过的节点
function EntryNodeOfLoop(pHead){
let flag = 0;
let node = pHead;
while(node) {
if(node.flag) return node;
node.flag = 1;
node = node.next;
}
}
方法2: 快慢指针,记录第一次出现过的节点
通过定义slow和fast指针,slow每走一步,fast走两步,若是有环,则一定会在环的某个结点处相遇(slow == fast),这个时候,快慢指针距离头节点的距离是一样的。
- 头节点到入口节点有a点,环中的节点有b个
- 设fast指针走过的节点数是f,
- slow指针走过的节点数是s,
- 那么有以下两个结论:
-
- f = 2 * s (即快指针走过的节点数一定是慢指针的两倍)
-
- f = s + nb (当两者相遇时,快指针一定已经绕环走了n圈)
- 上面表达式得出
s = nb,
- 相遇时慢指针已经走了nb步,要走到入口节点,需要走a + kb步,而这时s = nb 慢指针只要再走a即可到达入口,a刚好是头节点到入口节点的距离。
- 此时若把快指针移动到头节点,然后和🈵慢指针一样的速度,当它们相遇时所处的位置就是入口节点
function EntryNodeOfLoop(pHead)
{
let fast = pHead;
let slow = pHead;
while(fast && fast.next) {
fast = fast.next.next;
slow = slow.next;
if(slow === fast) break;
}
if(fast == null || fast.next == null) return null;
fast = pHead;
while(fast !== slow) {
fast = fast.next;
slow = slow.next;
}
return slow;
}