首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【LeetCode刷题指南】--环形链表,环形链表II(附结论证明过程)

【LeetCode刷题指南】--环形链表,环形链表II(附结论证明过程)

作者头像
草莓熊Lotso
发布2025-10-29 12:07:47
发布2025-10-29 12:07:47
1070
举报
文章被收录于专栏:C++/LinuxC++/Linux

🔥个人主页:@草莓熊Lotso 🎬作者简介:C++研发方向学习者 📖个人专栏: 《C语言》 《数据结构与算法》《C语言刷题集》《Leetcode刷题指南》 ⭐️人生格言:生活是默默的坚持,毅力是永久的享受。

前言: 在这篇博客中,博主会为大家分享两个经典的题目,都会用到快慢指针以及相关结论。这些结论会有相关的证明过程,大家一定要注意看一下。


1.环形链表

题目链接:141. 环形链表 - 力扣(LeetCode)

题目描述:

题目示例:

思路: 快慢指针,慢指针每次走一步,快指针每次走两步,如果slow和fast指向同一个节点,说明链表带环

解题过程:

1.创建快慢指针,循环条件的话分奇数和偶数讨论,这里就不详细说了

2.如果快慢指针可以相遇,则返回true

3.如果快慢指针循环结束后还没有相遇,则返回false

具体过程图示如下:

复杂度:

  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

代码演示:

代码语言:javascript
复制
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
bool hasCycle(struct ListNode *head) {
    ListNode*slow=head;
    ListNode*fast=head;

    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;

        if(slow==fast)
        return true;
    }
    return false;
}

结论: 快慢指针,慢指针每次走一步,快指针每次走两步,两个链表从起始位置开始,如果链表带环则一定会在环中相遇,否则快指针先走到链表末尾

证明过程如下图:

提示: 虽然已经证明了快指针不论走多少步都可以满足在带环链表中相遇,但是在编写代码的时候 会有额外的步骤引入,涉及到快慢指针的算法题中通常习惯使用慢指针走一步快指针走两步 的方式。

我们就来看看如果快指针走3步的代码吧

代码语言:javascript
复制
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
typedef struct ListNode ListNode;
bool hasCycle(struct ListNode* head) {
    ListNode *slow, *fast;
    slow = fast = head;
    while (fast && fast->next) {
        slow = slow->next;
        int n = 3; // fast每次⾛三步
        while (n--) {
            if (fast->next)
                fast = fast->next;
            else
                return false;
        }
        if (slow == fast) {
            return true;
        }
    }
    return false;
}

2.环形链表II

题目链接:142. 环形链表 II - 力扣(LeetCode)

题目描述:

题目示例:

思路: 快慢指针在环理一定会相遇,相遇点到入环节点距离等于头节点到入环节点距离,一个从头节点出发,一个从相遇点除法最后一定会在入环节点相遇

解题过程:

1.定义快慢指针,判断能不能相遇

2.如果可以相遇,成环,继续判断,根据结论利用pcur!=slow遍历,直到它们相遇就返回pcur,这样就找到了入环节点

3.如果不能相遇,环都成不了,直接返回NULL

具体过程图示如下:

复杂度:

  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

代码演示:

代码语言:javascript
复制
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
struct ListNode *detectCycle(struct ListNode *head) {
    ListNode*slow=head;
    ListNode*fast=head;

    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;

        if(slow==fast)
        {
            ListNode*pcur=head;
            while(pcur!=slow)
            {
                pcur=pcur->next;
                slow=slow->next;
            }
            return pcur;
        }
    }
    return NULL;
}

结论: 快慢指针相遇点的到环的距离=头节点到入环节点的距离

证明过程如下图所示:


往期回顾:

【LeetCode刷题指南】--数组串联,合并两个有序数组,删除有序数组中的重复项

【LeetCode刷题指南特别篇】--移除链表元素,调试技巧,链表分割

【LeetCode刷题指南】--反转链表,链表的中间结点,合并两个有序链表

【LeetCode刷题指南】--链表的回文结构详解,相交链表

结语:本篇文章就到此结束了,《LetetCode刷题指南》中的题目比起之间的C语言刷题集中的题目,肯定会更加复杂一些。而且题目形式也不一样,大家需要注意一下。如果文章对你有帮助的话,欢迎评论,点赞,收藏加关注,感谢大家的支持

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-07-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.环形链表
  • 2.环形链表II
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档