【数据结构】习题之判断链表是否有环和返回链表入环后第一个节点

本文详细探讨了链表中判断是否有环以及返回入环后第一个节点的算法,利用快慢指针策略,并分析了追击过程中距离变化的规律,包括特殊情况下的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  👑个人主页:啊Q闻       

🎇收录专栏:《数据结构》           

 🎉前路漫漫亦灿灿

前言 

判断链表是否有环和返回链表入环后第一个节点这两道题目时相关联的,所以将两道题目放在一起来看看。这篇博客会详细分享一下两道题目的思路。

链表中是否有环 

题目为:. - 力扣(LeetCode)

思路为:

定义快慢指针,快指针fast每次走两步,慢指针slow每次走一步,如果链表带环的话,快慢指针一定会在环内相遇。如果没有环,快指针会先走到空。 


 但是大家有没有这个疑问:

slow走一步,fast走两步,一定可以追上吗?

分析:fast先入环,过一段时间,slow也会入环,假设slow入环后,fast与slow之间的距离为             N,每追击一次,他们之间的距离就会缩小一步。 

所以追击过程fast和slow的距离变化为:

N

N-1

N-2

N-3

……

0(当其变化为0时,代表其追上了)

slow走两步,fast走三步,可以追上吗?

分析:fast先入环,slow再入环,假设fast与slow之间的距离为N,每追击一次,他们之间的距             离就会缩小两步。

所以追击过程fast和slow的距离变化为:

N

N-2

N-4

N-6

…… 

当N为偶数时,为0,代表其可以追上

当N为奇数时,为-1,代表其错过了,两者会进行新一轮的追击,此时他们之间的距离变为C-1(C为环的长度),所以当C-1为偶数时,可以追上,当C-1为奇数时,则永远不可能追上。


那么,是否存在永远追不上的条件:N为奇数,C-1同时也为奇数呢?

分析:这里我们需要知道,快慢指针相遇是在入口点,第二道题目会有证明。

代码实现:

bool hasCycle(struct ListNode *head) {
    struct ListNode*fast,*slow;
    fast=slow=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
        if(slow==fast)//环存在一定可以追上
        {
            return true;
        }
    }
    return false;
}

返回链表入环后第一个节点 

题目为:. - 力扣(LeetCode)

思路为:

定义快慢指针,两个指针会在入口点相遇,我们证明一下 

 证明一下:

代码实现:

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode*fast,*slow;
    fast=slow=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
        if(fast==slow)//相遇就代表有环
        {
            struct ListNode*meet=slow;
            while(head!=meet)//在入口点相遇
            {
                meet=meet->next;
                head=head->next;
            }
            return meet;
        }
    }
    return NULL;
}

大家有没有感觉这两道代码比较麻烦的地方不是代码本身,而是其的推理逻辑呀,谢谢大家阅读,如果对你有帮助的话,三连支持一下吧 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值