快慢指针问题

目录

  • [1. 环形链表](#1. 环形链表)
  • [2. 环形链表2](#2. 环形链表2)

这个问题是个经典问题。这个推导过程要理解

1. 环形链表

https://leetcode.cn/problems/linked-list-cycle/description/

这个问题如果直接遍历链表,走一圈看有没有出现过的地址,需要把所有地址记录下,这样时空复杂度都是O(n),现在想要更好的空间复杂度。

  • 考虑使用两个指针,一个快一个慢,快指针的速度是慢指针的两倍,它们同向行驶,这样,如果链表有环,这俩指针一定能够在某个位置相遇(差值是1的整数倍,n步走完一定能够构造出环长的整数倍)
  • 上面这个图比较详细
c 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        ListNode* fast = head;
        ListNode* slow = head;
        while(fast != NULL && slow != NULL && fast -> next != NULL) {
            fast = fast -> next -> next;
            slow = slow -> next;
            if(fast == slow) {
                return true;
            }
        }
        return false;
    }
};

2. 环形链表2

https://leetcode.cn/problems/linked-list-cycle-ii/

  • 在第一个问题里面,我们知道了可以用一个速度为 2 2 2的快指针和一个速度为 1 1 1的慢指针来判断链表是否有环。现在这个问题,让我们找入环点是哪一个,还是看下面这个图
  • 这里设 b b b是慢指针跟快指针相遇的时候,它走的步数,那么快指针因为速度是它的两倍,所以走了 2 b 2b 2b步,所以 2 b − b 2b-b 2b−b就是快指针比慢指针多走了多少圈,这里设为 k k k圈,所以 2 b − b = b = k c 2b-b=b=kc 2b−b=b=kc。对于慢指针来说,走到相遇点的时候,有 b − a = k c − a b-a=kc-a b−a=kc−a,那么在相遇点,再走a步就能走到入环点了,这跟头节点到入环点的距离刚好相等,这个时候,如果把头节点放上一个跟慢指针一样速度的指针,让慢指针从相遇点继续走。正好能跟头节点的指针相遇。这样就找到了入环点
c 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* fast = head;
        ListNode* slow = head;
        while(slow != NULL && fast != NULL && fast -> next != NULL) {
            if(slow == NULL || fast -> next == NULL) {
                return NULL;
            }
            slow = slow -> next;
            fast = fast -> next -> next;
            if(fast == slow) {
                fast = head;
                while(fast != slow) {
                    fast = fast -> next;
                    slow = slow -> next;
                }
                return fast;
            }
        }
        return NULL;
    }
};
相关推荐
Hcoco_me4 分钟前
大模型面试题49:从白话到进阶详解SFT 微调的 Loss 计算
人工智能·深度学习·神经网络·算法·机器学习·transformer·word2vec
武子康5 分钟前
大数据-206 用 NumPy 矩阵乘法手写多元线性回归:正规方程、SSE/MSE/RMSE 与 R²
大数据·后端·机器学习
修炼地6 分钟前
代码随想录算法训练营第五十三天 | 卡码网97. 小明逛公园(Floyd 算法)、卡码网127. 骑士的攻击(A * 算法)、最短路算法总结、图论总结
c++·算法·图论
小王和八蛋6 分钟前
负载均衡之DNS轮询
后端·算法·程序员
风象南10 分钟前
Spring Boot 统一日志上下文
后端
炽烈小老头12 分钟前
【每天学习一点算法 2026/01/07】Fizz Buzz
学习·算法
青梅主码13 分钟前
IBM最新发布《2026年的五大趋势》:不确定性成最大资产,AI与量子将重塑未来
后端
小王和八蛋14 分钟前
分布式软负载均衡:策略、对比与选型
后端
数据大魔方18 分钟前
【期货量化实战】威廉指标(WR)策略:精准捕捉超买超卖信号(Python源码)
开发语言·数据库·python·算法·github·程序员创富
why技术19 分钟前
可怕,看到一个冷血的算法。人心逐利,算法只会更聪明地逐利。
前端·后端·算法