每日算法 -- 链表
42. 环形链表 II
分析
- 一道写了 n 次的题目,主要要注意的是,后面启动的点,必须要和 slow 和 fast 启动的位置一致
- 快慢指针直接判断是否存在环
- 当存在环后,在起点启动一个新的指针,慢指针继续往前走,当这两个指针相交的时候,就是进入环的位置
- 设启动点到闭环节点长度为 S,环长度为 C ,快慢指针相交时距离闭环节点的距离是 l
- 根据快慢指针最后相交可以得到两个等式,消除速度遍历后得到一个等式 S+(2m-n)C+l = 0 ,其中 m 是慢指针转环的次数,n 是快指针转环的速度
- 现在新,慢指针继续往前走,我们求新节点到达闭环节点时,慢节点的位置:由于启动的时候距离闭环节点是 l,现在又走了 S,所以在这一个阶段,慢节点走了闭环节点距离 l+S 的位置,然后将 S 转换成以 C 和 l表示的等式,得到 l+ S =(n-2m)C, 也就是刚好是一圈的 n-2m 倍,所以就是刚好也在闭环节点上,所以可以直接返回
// 142. 环形链表 II
// https://leetcode-cn.com/problems/linked-list-cycle-ii/
/**
* @分析
* 1. 就是找入环第一个节点
*/
var detectCycle = function (head) {
if(!head) return head // 空节点直接返回
let emptyNode = new ListNode()
emptyNode.next = head
let slow = fast = emptyNode // 都是从 emptyNode 开始跑
slow = slow.next
fast = fast.next.next
while (fast && fast.next) {
if(slow === fast){
// 在环内重合了
let cur = emptyNode
while(cur !== slow){
// slow 指针继续走
slow = slow.next
cur = cur.next
}
// 当他们重合的时候,就是启动的节点
return cur
}
slow = slow.next
fast = fast.next.next
}
// 无环,走到了 null
return null
};
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情