快慢指针问题

目录

  • [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;
    }
};
相关推荐
weixin_446260851 小时前
HACO:面向动态部署环境的对冲式智能计算可靠多智能体调度框架
后端·python·flask
爱刷碗的苏泓舒2 小时前
PPP-AR 中的参考星选取:数学原理、评价指标与切换处理
算法·gnss·模糊度固定·ppp-ar·星间单差·参考星·卫星端偏差
ttwuai2 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
用户8356290780512 小时前
Python 实现 Excel 页面布局与打印设置自动化
后端·python
用户9931441579842 小时前
微服务框架中获取用户信息
后端
xuanWb2 小时前
手写一个 LLM API 网关:Anthropic 与 OpenAI 协议转换的完整实现
后端
苍何3 小时前
给 Codex 换皮肤这门生意,被我开源了
后端
用户8356290780513 小时前
Python 实现 Excel 命名范围(Named Range)的创建与管理
后端·python
程序员David3 小时前
我让 Claude 从架构文档一路干到代码,踩了三个坑才摸清边界
后端