快慢指针问题

目录

  • [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;
    }
};
相关推荐
IronMurphy2 小时前
【算法四十三】279. 完全平方数
算法
墨染天姬2 小时前
【AI】Hermes的GEPA算法
人工智能·算法
papership2 小时前
【入门级-数据结构-3、特殊树:完全二叉树的数组表示法】
数据结构·算法·链表
smj2302_796826522 小时前
解决leetcode第3911题.移除子数组元素后第k小偶数
数据结构·python·算法·leetcode
小码哥_常3 小时前
解锁AI编程密码:程序员常用的10个AI提示词
后端
Beginner x_u3 小时前
链表专题:JS 实现原理与高频算法题总结
javascript·算法·链表
直奔標竿4 小时前
Java开发者AI转型第二十七课!Spring AI 个人知识库实战(六)——全栈闭环收官,解锁前端流式渲染终极技巧
java·开发语言·前端·人工智能·后端·spring
金銀銅鐵4 小时前
[java] 编译之后的记录类(Record Classes)长什么样子(上)
java·jvm·后端
uzong5 小时前
我研读了 500 个 Spring Boot 生产级代码库,90% 都犯了这 7 个致命错误
后端
xiaobaoyu6 小时前
ssm知识点梳理
后端