写点什么

快慢指针算法

作者:秋名山码民
  • 2022 年 6 月 25 日
  • 本文字数:869 字

    阅读完需:约 3 分钟

快慢指针算法思想:

  1. 定义快慢指针 fast 和 slow,起始均位于链表头部。规定 fast 每次后移 2 步,slow 后移 1 步;

  2. 若 fast 遇到 null 节点,则表示链表无环,结束;

  3. 若链中有环,fast 和 slow 一定会再次相遇;

  4. 当 fast 和 slow 相遇时,额外创建指针 ptr,并指向链表头部,且每次后移 1 步,最终 slow 和 ptr 会在入环点相遇。


142. 环形链表 II - 力扣(LeetCode)


public class Solution {     public ListNode detectCycle(ListNode head) {         if (head == null) {             return null;         }         ListNode slow = head, fast = head;         while (fast != null) {             slow = slow.next;             if (fast.next != null) {                 fast = fast.next.next;             } else {                 return null;             }             if (fast == slow) {                 ListNode ptr = head;                 while (ptr != slow) {                     ptr = ptr.next;                     slow = slow.next;                 }                 return ptr;             }         }         return null;     } }
复制代码

为什么 fast 指针每次移动 2 步,能不能移动 3、4、5...步?

设环外长度为 w,环长度为 s。取一特殊值 j,保证 j>w 且是 s 整数倍的最小值。将 slow 走了 j 步后的位置记为 X(j),则 fast 走了 kj 步,记为 X(kj),其中 k 为 fast 与 slow 的速度比值。

因为 j>w,所以 slow 和 fast 都在环内,而且 X(kj)可以看做从 X(j)出发,走了(k-1)*j 步,因为 j 是环长的整数倍,所以又回到了 X(j),两者相遇。

从上面的分析可知,无论 fast 取任何值,两者都会相遇。即使比值 K 是小数 2.3(如 slow=10,fast=23),也只需要 j 乘以 10,就证明了这个问题。

我们之所以取 fast=2,是因为快指针的时间复杂度为 O(n*fast),可以保证算法效率最高。


  • 时间复杂度:O(N),N 为链表节点数量,通过问题 2、问题 3 的解答,slow 与 fast 相遇时,slow 不会绕环超过一周;寻找入环点时,也只走了环外距离 a。因此,总的执行时间为:


  • 空间复杂度:O(1)。因为只使用了 slow、fast、ptr 三个指针。

发布于: 刚刚阅读数: 4
用户头像

卷不死,就往…… 2021.10.19 加入

2019NOIP退役成员,华为云享专家,阿里云专家博主,csdn博主,努力进行算法分享,有问题欢迎私聊

评论

发布
暂无评论
快慢指针算法_算法_秋名山码民_InfoQ写作社区