142 Linked List Cycle II

25 年 6 月 24 日 星期二
422 字
3 分钟

142. Linked List Cycle II

Screenshot 2025-11-04 at 12.20.37 pm

解:https://leetcode.cn/problems/linked-list-cycle-ii/solutions/12616/linked-list-cycle-ii-kuai-man-zhi-zhen-shuang-zhi-

Screenshot 2025-11-04 at 12.22.51 pm

slow慢指针走了s步,fast快指针走了f步

根据:

  1. f = 2s (快指针每次2步,路程刚好2倍)
  2. f = s + nb (相遇时,刚好多走了n圈)

推出:s = nb (s走的步数刚好是n倍的环长)

从head结点走到入环点需要走 : a + nb, 而slow已经走了nb,那么slow再走a步就是入环点了。

如何知道slow刚好走了a步? 从head开始,和slow指针一起走,相遇时刚好就是a步

为什么走a步之后会相遇:

入口为 a + nb,当n = 0时和 n属于正整数时都表示环的入口。

My solution:

js
/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */

/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var detectCycle = function (head) {
  let slow = head,
    fast = head
  if (!(fast && fast.next)) {
    // 特判空链表及只有一个元素的链表
    return null
  }
  while (fast && fast.next) {
    // 找到相遇点, fast 和 slow 指针分别走了 2n,n 个环的周长。
    fast = fast.next.next
    slow = slow.next
    if (fast === slow) {
      break
    }
  }
  if (fast !== slow) {
    // 无环
    return null
  }
  fast = head
  while (fast !== slow) {
    // fast 和 slow共同走a步,之后在入口相遇
    slow = slow.next
    fast = fast.next
  }
  return slow
}
js
/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */

/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var detectCycle = function (head) {
  let slow = head,
    fast = head
  while (true) {
    if (!(fast && fast.next)) {
      return null
    }
    slow = slow.next
    fast = fast.next.next
    if (fast === slow) {
      break
    }
  }
  fast = head
  while (fast !== slow) {
    fast = fast.next
    slow = slow.next
  }
  return slow
}

文章标题:142 Linked List Cycle II

文章作者:Sirui Chen

文章链接:https://blog.siruichen.me/posts/142linked_list_cycle_ii[复制]

最后修改时间:


商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但是分发衍生作品时必须采用相同的许可协议。
本文采用CC BY-NC-SA 4.0进行许可。