给定一个链表,如果它是有环链表,实现一个算法返回环路的开头节点。若环不存在,请返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
解题思路
题目是求环形链表入环的位置
- 首先判断链表是否为环形链表
- 接下来再找入环的位置 设:
- 设链表中环外部分的长度为 a
- 当slow走到入环位置时,fast在距离入环位置a的地方
- 此时如果要让slow和fast相遇,且fast比slow每次多走一步,那么fast需要走x步才能追到slow
- 设fast继续往前走到入环位置的距离为x
slow fast
head---a----入环-----a-------
| |
|--------------
x
此时slow在环中比fast多走了x的距离,fast要想追上slow,就需要再走2x才能到达他们的相遇位置 而次时,slow走到了与入环起始点位置相距为x的地方
x
head---a----入环-------------
| |
|-------------相遇位置 slow fast
a
由于我们知道环的长度为 a + x,那么可以确定相遇位置到入环位置的距离为 a.
代码
var detectCycle = function(head) {
let fast = slow = head;
while (fast) {
(fast = fast.next) && (fast = fast.next);
slow = slow.next;
if (slow === fast) break;
}
if (!fast) return null;
let pre = head;
while (pre !== slow) {
pre = pre.next;
slow = slow.next;
}
return pre;
};