当前位置: 首页 > article >正文

力扣——环形链表问题

判断链表是否有环以及入环的第一个节点

  • 前言
  • 判断链表是否有环
  • 找到入环的第一个节点

前言

    大家好,前段时间,熊二学习了关于环形链表相关的问题,以下是我的见解,希望能够帮助你们呀!

判断链表是否有环

给定一个链表,判断链表中是否有环。OJ链接
环形链表
方法:快慢指针
思路:

  如果没有环,快指针永远比慢指针快,,在这个追击问题中,慢指针永远追不上快指针,那么快慢指针永远都不会相遇,说明它们在一条直线上跑 ,故没有环。
在这里插入图片描述
  如果有环,假设快指针是慢指针速度的两倍,那么快指针一定比慢指针先进入环,等慢指针开始进入环,这个追及问题就开始了,在同一个环中,快指针和慢指针速度不一至,快指针一定会追上慢指针的,当快指针=慢指针时,表明一定有环。
在这里插入图片描述

代码如下:

bool hasCycle(struct ListNode *head) {
    struct ListNode *fast = head,*slow = head;
    while(fast&&fast->next)
    {
        slow = slow->next;
        fast = fast->next;
        if(slow == fast)
         return true;
    }
    return false;
}

拓展问题:
1.为什么会相遇,有没有可能错过,永远追不上,请证明。

假设slow进环时,fast跟slow的距离是N,fast追击slow的过程距离变化如下:
N-1
N-2

3
2
1
0
每追击一次,fast与slow的距离是-减1,最后一定会追上
在这里插入图片描述

2.slow一次走1步,fast走3步,4步,5步,n步,一定能追上吗?请证明。

假设slow进环时,fast跟slow的距离是N,fast追击slow的过程距离变化如下:
若N为偶数         若N为奇数
N-2                 N-2

N-4                 N-4
…                  …
4                    3
2                    1
0                    1
追上了             错过了,进入新一轮的追击
                   新一轮,距离变成了C-1
                   C-1为偶数,下一轮就追上了
                   C-1为奇数,下一轮会不会追上呢?
在这里插入图片描述
关于C-1为奇数,下一轮会不会追上呢?

我们暂且把问题变换成,如果同时存在N是奇数且C是偶数,fast会不会追上slow?

假设slow进环时,fast跟slow的距离是N
slow走的距离:L
fast走的距离:L+xC+C-N;
slow进环时,假设fast已经在环里面转了x圈
fast走的距离是slow的3倍
3
L =L+ xC +C-N;
化简:
2
L= (x+1)*C+C-N;
偶数 =(x+1)*偶数-奇数
如果同时存在N是奇数且C是偶数,
偶数 =(x+1)*偶数-奇数 ,不存在 ,所以,永远追不上不成立
总结:一定能够追上

找到入环的第一个节点

给定一个链表,返回链表开始入环的第一个结点。 如果链表无环,则返回 NULL。OJ链接
在这里插入图片描述

运动过程:
在这里插入图片描述

首先,我们指定快指针fast,慢指针slow,快指针以慢指针两倍的速度走(两指针同时走)。

当快指针进环时,慢指针还在追赶(红色)
当慢指针进环时,快指针已经在环里面(蓝色),这时,不久后,快指针就会追上慢指针(在这个环中)
当快指针追上慢指针时(紫色),我们从中寻找等式。

设AB=L,BC=N,环的总长度为C,寻找关系
slow的路程:L+C-N
fast的路程:L+XC+C-N
fast是slow路程的两倍:2
(L+C-N)=L+X*C+C-N;
继而得出:L=(X-1)*C+N;
因为C是圆环的长度,所以fast不管是多走X-1圈,还是多走了1圈,都没有区别,最后得出:L=N这个关键条件

代码如下:

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

在这里插入图片描述


http://www.kler.cn/news/361563.html

相关文章:

  • 告别微信封号!学会这5招,让你的账号坚不可摧
  • 递归算法之二分搜索(Binary Search)详细解读
  • 【日志】Unity3D模型导入基本问题以及浅谈游戏框架
  • 浪潮云启操作系统(InLinux)bcache缓存实践:理解OpenStack环境下虚拟机卷、Ceph OSD、bcache设备之间的映射关系
  • HTTP协议讲解
  • 一起赚美元第九期及相关推荐
  • 是管理员用户但总是提示需要管理员权限的问题。(win11、win10、win7)
  • 【运维心得】5G你肯定在用,5GC是什么?
  • 在MySQL中使用B+ 树索引如何查找连带表数据
  • Pr 视频效果:视频限制器
  • 2-2(补充) opencv实战进阶系列 最大多边形识别
  • 「JVS更新日志」低代码、智能BI、逻辑引擎10.23功能更新说明
  • linux 离线安装redis
  • MySQL datetime不同长度的影响
  • ElasticSearch的向量存储和搜索
  • Android 系统SELinux
  • Leetcode—91. 解码方法【中等】
  • 华为配置 之 Console线路配置
  • PCB生产制造商强达电路,公布网上申购情况及中签率
  • 威胁狩猎:基于ELK的日志监控
  • 【最新华为OD机试E卷-支持在线评测】生成哈夫曼树(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)
  • 要卸载 RVM(Ruby Version Manager)和它管理的所有 Ruby 版本
  • 深度学习——循环神经网络RNN知识点小结(全)
  • Django学习-模板层_过滤器和继承
  • 【数据安全】企业数据安全防护体系
  • 十种排序方法