【C】leetcode力扣—— 142. 环形链表 II

本文解析了如何利用快慢指针算法解决LeetCode上的环形链表II问题,包括判断链表是否存在环以及找到链表开始入环的第一个节点。通过分析快慢指针移动距离的关系,可以在O(1)空间复杂度下完成求解。
摘要由CSDN通过智能技术生成

142. 环形链表 II

题目链接: https://leetcode.cn/problems/linked-list-cycle-ii/

题目

题目

  • 给定一个链表的头节点 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 或者链表中的一个 有效索引 。

进阶: 你是否可以使用 O(1) 空间解决此题?

解题思路分析

根据题目,我们可以把题目分成两个问题分析

  • 如何判断是否有环
  • 如果有环如何返回链表开始入环的第一个节点

1.如何判断是否有环

这个问题在之前的环形链表Ⅰ文章中已经详细分析过了。
感兴趣的话点击链接:http://t.csdnimg.cn/zmymE

2.如果有环,如何返回链表开始入环的第一个节点

我们画图进行分析
我们假设:

  • 入口点环入口点为:L
  • 入口点相遇点为:X
  • 环的长度C
    在这里插入图片描述
  1. 那么从开始到相遇时slow走的距离为:L+X
  2. slow还没有进入环中L足够大时,fast在环中已经走了n
  3. 那么从开始到相遇时fast走的距离为:L+n*C+X

fast路程=slow路程*2
2*(L+X)=L+n*C+X
L+X=n*C
L=n*C-X

通过上面分析,得出结论:

  • 我们让一个指针从相遇点开始走,另一个指针在开始点开始走
  • 那么两个指针会在环的入口点相遇

(这块比较难理解,如果不理解的话可以自己画图分析一下)

这时我们就解决了找环的入口的问题!

代码

附代码:

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode* slow=head;
    struct ListNode* fast=head;
    while(fast&&fast->next)
    {
        slow=slow->next;//一步
        fast=fast->next->next;//两步
        
        if(slow==fast)//相遇
        {
        	//让cmp从相遇点开始走
            struct ListNode* tmp =slow;
            //head从开始点开始走
            while(head!=tmp)
            {
                head=head->next;
                tmp=tmp->next;
            }
            return tmp;
        }
    }
    return NULL;
}

※ 如果文章对你有帮助的话,可以点赞收藏!!谢谢支持

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一岁就可帅-

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

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

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

打赏作者

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

抵扣说明:

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

余额充值