不管全世界所有人怎么说,我都认为自己的感受才是正确的。无论别人怎么看,我绝不打乱自己的节奏。喜欢的事自然可以坚持,不喜欢的怎么也长久不了。
LeetCode:原题地址
题目要求
给定一个链表,返回链表开始入环的第一个节点。如果链表无环,这返回null。
如果链表中有某个节点,可以通过跟踪next指针再次到达,则链表中存在环。为了表示给定链表中的环,使用整数pos表示链表尾连接到链表中的位置(索引从0开始)。如果 pos 是 -1,这在该链表中没有环。
不允许修改链表\
例1:
输入: head = [3,2,0,-4], pos = 1
输出: 返回索引为 1 的链表节点
解释: 链表中有一个环,其尾部连接到第二个节点。
复制代码
输入: head = [1,2], pos = 0
输出: 返回索引为 0 的链表节点
解释: 链表中有一个环,其尾部连接到第一个节点。
复制代码
输入: head = [1], pos = -1
输出: 返回 null
解释: 链表中没有环。
复制代码
思路
思路来自官方的Floyd动态规划算法 每次迭代,p0跳一节点,速度1,p1跳双节点,速度2
不存在,p0或p1为null 存在环,p1超p0一圈,相遇图点A,求点B p0的路程:a + b p1的路程:a + b + c + b p1速度是p0的2倍,时间一定,p0的路程 * 2 = p1的路程 (a + b) * 2 = a + b + c + b,解a = c 当p0和p1相遇点A时,新指针从起始点向B走 p0和新指针速度都为1,路程相同,两者终会相遇点B,返回p0指向节点 存在环,p1超p0 n圈,相遇图A,求点B,p1路程:a + b + (c + b) * n。(a + b) * 2 = a + b + (c + b) * n
- a = (c + b) * n - b = (c + b) * (n - 1) + c + b - b = c + (c + b) * (n - 1)
- a = c + (n - 1) * 圈,无论超多少圈,最后一圈的情况都与超1圈时相同
代码
var detectCycle = function(head) {
var p = [head, head]
while (p[0] && p[1]) {
p = [p[0].next, p[1].next ? p[1].next.next : null]
if (p[0] && p[0] === p[1]) {
while (head) {
if (p[0] === head) return head
p[0] = p[0].next, head = head.next
}
}
}
return null
};