leetcode -- 142. 环形链表 II

48 篇文章 1 订阅
文章介绍了如何使用快慢指针检测环形链表并找到环的入口点。在链表中,快指针每次前进两步,慢指针前进一步,若存在环,快指针将追上慢指针。确定入口点的方法是让一个指针从相遇点开始,另一个从头节点开始,它们将在入口点相遇。
摘要由CSDN通过智能技术生成

在这里插入图片描述

📜1. 题目

给定一个链表的头节点 head,返回链表开始入环的第一个节点。 如果链表无环,则返null

如果链表中有某个节点,可以通过连续跟踪next指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数pos来表示链表尾连接到链表中的位置(索引从 0 开始)。如果pos-1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改链表。

示例1:
在这里插入图片描述

输入: head = [3,2,0,-4], pos = 1
输出: 返回索引为 1 的链表节点
解释: 链表中有一个环,其尾部连接到第二个节点。

示例 2:
在这里插入图片描述

输入: head = [1,2], pos = 0
输出: 返回索引为 0 的链表节点
解释: 链表中有一个环,其尾部连接到第一个节点。

示例 3:
在这里插入图片描述

输入: head = [1], pos = -1
输出: 返回 null
解释: 链表中没有环。

提示:

  • 链表中节点的数目范围是 [0, 104]
  • -105 <= Node.val <= 105
  • pos-1 或者链表中的一个有效索引

🔍2. 思路

🔑2.1 链表是否带环

这里的思路十分简单,即用快慢指针,一个快指针fast每次走两步,一个慢指针slow每次走一步,如果链表是带环的,就演变成了追击问题,当慢指针进环,快指针开始追击。
在这里插入图片描述

🔑2.2 为何能追上

思路较好理解,但是 为何快指针一定能追上慢指针,会不会出现追不到的情况? 这还需要我们进一步求证。

我们这里设置的快慢指针,他们的速度差为1,即如果开始追击,快指针fast与慢指针slow的距离每次缩小1。
在这里插入图片描述

如果慢指针slow每次走一步,快指针fast每次走n步,那么还一定能够追上吗?

这就需要分情况讨论,因为每次缩小的距离不是1,可能会出现错过的情况:
在这里插入图片描述

题外话:
我们不也是这个环里的“快指针”嘛,都在追击着属于我们的“慢指针”。
在这个快节奏的时代,走的太快,可能会忽略很多美好的风景,最终的结果也可能不是自己想要的。
那我们不妨放慢脚步,看看我们来时的路,调整好状态再出发,一步一个脚印。

🔑2.3 入口点的确定

在这里插入图片描述

tips:
这里fast走的距离不可认为是L+C+X,因为环的大小不确定,可能在slow入环之前,fast已经在环里面走了几圈了:
在这里插入图片描述

这样我们就能得出一个结论:一个指针从相遇点走,一个指针从起始点走,会在入口点相遇。

🔓3. 代码实现

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode* fast = head;
    struct ListNode* slow = head;
    while(fast && fast->next)
    {
        fast = fast->next->next;
        slow = slow->next;
        if(fast == slow)
        {
            struct ListNode* meet = slow;
            struct ListNode* start = head;
            while(meet != start)
            {
                meet = meet->next;
                start = start->next;
            }
            return meet;
        }
    }
    return NULL;
}

📡4. 题目链接

leetcode – 141. 环形链表
leetcode – 142. 环形链表 II

评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

加法器+

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值