码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 【数据结构初阶】详解 环形链表:链表的带环问题(判断是否带环、环形链表的入口点)


    文章目录

    • 一、链表的带环问题
      • 1.1、判断链表是否带环(力扣 141.环形链表)
      • 1.2 、证明:为什么带环时快慢指针一定相遇?
      • 1.3、证明:当slow走1步,fast可走3/4/5步(fast的速度是slow的3/4/5倍)吗?
        • 1.3.1、slow走1步,fast走3步
        • 1.3.2、slow走1步,fast走4步
      • 1.4、代码
      • 2.1、判断环形链表的入口点(力扣 142.环形链表2)
        • 2.1.1、方法一:相遇
        • 2.1.2、方法二:链表的相交
      • 2.2、代码
    • 二、谢谢观看!

    一、链表的带环问题

    1.1、判断链表是否带环(力扣 141.环形链表)

    题目:给你一个链表的头节点 head ,判断链表中是否有环。如果链表中存在环 ,则返回 true 。 否则,返回 false 。

    带环:链表的尾节点的next指向链表中的任一节点。
    环形链表如下:
    在这里插入图片描述
    方法:快慢指针(追击相遇问题)
    快指针:fast,慢指针:slow
    令fast的速度是slow的2倍,那么在相同的时间内,fast走过的路程是slow的2倍。
    故可得:
    在这里插入图片描述
    结论:若带环,快指针fast一定能追上slow,即fast与slow一定会相遇。
    若不带环,fast先到达尾节点,结束,此时fast一定在尾,slow在中间,不会相遇。

    1.2 、证明:为什么带环时快慢指针一定相遇?

    在这里插入图片描述
    当二者间距离变为0时,fast与slow相遇。

    在这里插入图片描述
    如上图所示,随slow与fast的移动,二者间的距离一定会变为0,即fast与slow一定会相遇。

    1.3、证明:当slow走1步,fast可走3/4/5步(fast的速度是slow的3/4/5倍)吗?

    首先要明白一点:速度的倍数关系存在的根本原因是为了判断二者在该速度下一定能相遇。来作为判断是否带环的区分。所以如果能相遇(追上),就可以作为链表带环的判断条件。

    1.3.1、slow走1步,fast走3步

    在这里插入图片描述
    由上图可知:
    1、当N为偶数时,N最终能够变化为0,一定能相遇。
    2、当N为奇数时,设环的周长为C,距离变化为-1时,即fast快slow一步,那么第二轮追击时二者间距为N=C-1,那么若C-1为偶数,第二轮可以追上;若C-1为奇数,第二轮追不上。
    那么由上追不上的情况只有N为奇数且C-1为奇数。
    但是 由fast的总路程我们可以得到以下等式: 在这里插入图片描述得到等式 2L=(x+1)*C-N,等式左边为偶数,当N为奇数, C-1为奇数即C为偶数时,
    偶数-奇数不等于偶数,故此时等式不成立,所以不存在N为奇数,C-1为奇数的情况。

    结论:
    当N为偶数时,第一轮就能追上
    当N为奇数时,若C-1为偶数,第二轮能追上
    而N为奇数,C-1为奇数的情况不存在
    所以当slow走1步,fast走3步时一定可以追上。

    1.3.2、slow走1步,fast走4步

    相当于slow每走1步,二者的间距减少3
    在这里插入图片描述

    1.4、代码

    这里的循环条件是 fast不为空且fast->next不为空。
    原因:NULL不能再进行解引用操作。
    若fast为空,那么在fast=fast->next->next中,fast->next进行了解引用,程序报错。
    若fast->next为空,那么在fast=fast->next->next中,fast->next->next进行了解引用,程序报错。

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

    2.1、判断环形链表的入口点(力扣 142.环形链表2)

    题目:给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
    在这里插入图片描述

    2.1.1、方法一:相遇

    head为头指针,指向链表的头结点。
    meet为相遇指针,指向fast与slow相遇的位置。
    在这里插入图片描述
    结论:head与meet同时走,一定会在入口点相遇。
    证明:
    由上可得,本题一定要使用快慢指针的追击相遇,那么fast与slow有速度差,根据1.1的证明,我们还是使用速度为二倍关系比较容易。
    即 slow走1步,fast走2步。
    在这里插入图片描述
    在这里插入图片描述

    2.1.2、方法二:链表的相交

    在这里插入图片描述
    找到入口点后,再把环形链表还原即可。

    2.2、代码

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

    二、谢谢观看!

  • 相关阅读:
    EasyExcel 导入导出Excel文件
    图片链接或pdf链接通过浏览器打开时,有时可以直接预览,有时却是下载,为什么?
    2023后端面试题(持续性更新)
    目标检测YOLO实战应用案例100讲-船舶目标检测及编队识别(续)
    【Acwing1027】方格取数(动态规划)题解
    hbuilder x配置 配置使用 vue-cli和微信开发者工具
    SparkCore系列-6、RDD 持久化
    使用 HTML、CSS 和 JS 制作一个中国象棋
    蚁剑加密 WebShell 过杀软
    printf如何打印指定长度-防止非NUL结尾的字符串造成的读越界漏洞的方法
  • 原文地址:https://blog.csdn.net/2302_79531041/article/details/140402598
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号