设计链表
一、LeetCode题解
瞧一瞧~
- 博健的LeetCode题解:Gitbook版本传送门
- 博健的LeetCode题解:CSDN传送门
- 前端进阶笔记:Gitbook传送门
二、算法题
题目
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。如果有环,则确定它的入口位置。
思路
- 第一阶段,我们先确定当前链表是否存在环
- 第二阶段,如果存在环,我们要确定入口的位置
- 入口前节点个数为
a
,环节点个数为b
; - 快节点走过的节点数 = 2 * 慢节点走过的节点数,即
f = 2s
; - 快节点走过的节点数 = s + nb(多揍了n倍的环)(相遇时);
- 由此得出:
s = nb
(相遇时); - 如果说慢指针走到入口的距离 k =
a + nb
,两点相遇时s = nb
,即再走a步即可; - 我们重新确定双指针(速度要相同),新指针走
a
步应该到达入口,慢指针走a
步也会到达入口; - 新指针推断为 头节点,两者相遇的节点为入口;
- 入口前节点个数为
代码
var detectCycle = function(head) {
var slow = head, fast = head;
while(fast && fast.next) {
// 如果 快指针 走到终点,证明无环
slow = slow.next;
fast = fast.next.next;
if (fast === slow) {
// 记录相遇点
// 新指针在起点,快指针在相遇点
// 两个节点再次相遇时,一定在入口点
var start = head;
while (start !== fast) {
start = start.next;
fast = fast.next;
}
return fast;
}
}
return null;
};