# 环形链表II(142)
# 题目
给定一个链表,返回链表开始入环的第一个节点
。 如果链表无环,则返回 null
。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。
# 说明
不允许修改给定的链表。
# 进阶:
你是否可以使用 O(1) 空间解决此题?
# 示例
输入:head = [3,2,0,-4]
, pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。
输入:head = [1,2]
, pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。
输入:head = [1]
, pos = -1
输出:返回 null
解释:链表中没有环。
# 提示
- 链表中节点的数目范围在范围 [0, 104] 内
- -105 <= Node.val <= 105
- pos 的值为 -1 或者链表中的一个有效索引
# 算法
# Set
使用Set
保存遍历过的每一个节点,如果有环,那么环的入口就是第一个在Set
中存在的节点
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
const detectCycle = (head) => {
const set = new Set();
while (head) {
if (set.has(head)) {
return true;
} else {
set.add(head);
head = head.next;
}
}
return false;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 标记
在每一个遍历过的节点上新增flag
属性用来判断链表是否成环
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
const detectCycle = (head) => {
while (head) {
if (head.flag) {
return head;
} else {
head.flag = true;
head = head.next;
}
}
return null;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 快慢指针
快慢指针同时从起点出发,我们设定:
- 起点到环入口的距离称为
a
- 在环中相遇时慢指针走过的环中的距离为
b
,令 - 慢指针没走的环的距离为
c
那么相遇时:
- 慢指针走过的距离是:
a+b
- 快指针走过的距离是
a+n(b+c)+b
,n为走的圈数
因为每时每刻快指针都是慢指针走过的距离的2倍,所以:
a+n(b+c)+b = a+b
化简得:
a = c+(n-1)(b+c)
即环外得距离
= n-1圈环的长度
+ 相遇时慢指针没有走的环的距离
所以我们设定一个指针从头节点开始,以相同的速度和慢指针同时移动,当他们相遇时(新的指针走过了环外的距离,慢指针走完了环中剩余的距离),即为环的入口
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
const detectCycle = (head) => {
let fast = head,
slow = head;
while (fast) {
slow = slow.next;
if (fast.next) {
fast = fast.next.next;
} else {
return null;
}
if (fast === slow) {
let node = head;
while (node !== slow) {
node = node.next;
slow = slow.next;
}
return slow;
}
}
return null;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28