链表OJ题第二弹:环形链表和环形链表 II

news2025/1/17 1:41:23

前言

第一弹的链表题目比较基础,下面两道题目难度升级,可以先自己挑战一下,再来看解析。解析有图示和的文字,有助于你的理解。


1. 环形链表

(1)题目及示例

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

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

示例1:

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

示例2:

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

示例3:

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

(2)解法

在环形链表中,从头结点开始出发,会进入到一个循环,不会停下来。我们可以用快慢指针来解决这个问题,慢指针走一步,快指针走两步。

如下图所示,因为它们两个指针没走一次,之间的距离就减小一步,并且它们之间的距离是整数一是任何整数的因子,所以fast指针一定能追上slow指针。

如何写成代码呢?我们可以写一个while循环,每次slow指针走一步,fast指针走两步,但是判断条件是什么?应该是该链表不是环形链表的情况。

  • 当有偶数个结点时,fast指针会直接到空指针,
  • 如果是奇数个结点的话,fast指针会走到空指针的前一个结点,再走的话就没跨过空指针。

所以判断的条件就是fast或者fast的next指针不为空。

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

(3)深入思考

我们上面已经证明了快指针走两步是一定可以追上的,那快指针一次走3步,走4步,一直到n步行吗?下面我将分析fast指针一次走3步的情况:

当N是奇数时,我们假设环形链表有C个结点。

所以会有一次追上了,两次追上了,还有永远追不上的情况。如果是fast指针一次走四步,也可以这么分析,只不过情况变复杂了。

结论:fast指针一次走大于两步,不一定追得上slow指针。

2.环形链表II

(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
解释:链表中没有环

(2)思路详解

在阐述解题思路之前,我们先想一下:

  1. 当slow指针进入环形链表的时候,fast指针在环中能走几圈?
  2. 当slow指针进入环形链表的时候,fast指针需要走几圈,它们才能相遇?

第一个问题,从头结点到环形链表的第一个结点的长度,和环形链表的长度是随机的,所以可能出现slow指针还没进入环形链表时,fast指针在环形链表中已走了一圈以上的情况。

第二个问题,当slow指针进入环形链表中,不管fast指针走了几圈,基本都在slow指针的前面。我们想一想,slow指针走完一圈,fast指针至少走两圈以上,并且fast指针还在slow指针的前面,所以slow指针在走第一圈的时候,一定被追上。

如上图所示,我们知道了slow指针和fast指针走过的距离,并且我们知道slow指针一次走一步,fast指针一次走两步,就有了这样的等式关系:

2(L+X) = L+X+nC (n >=1)

化简后得到:L = nC - X (n = 1,2,3,4……)

我们假设n = 1,于是就有了L = C - X。也就是说,两个指针分别从头结点和相遇结点开始,一次走一步,当他们两个指向的地址相同时,这就是环形链表的第一个结点。那n不是1呢?结论也成立,只不过从相遇结点开始的指针需要再环中走上一圈以上。代码如下:

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.coloradmin.cn/o/1470433.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言菜鸟入门·二维数组

C语言菜鸟入门数组简介-CSDN博客 目录 ​编辑 1. 二维数组 1.1 初始化二维数组 1.2 访问二维数组元素 1.3 示例演示 2. 传递数组给函数 2.1 形式参数是一个指针 2.2 形式参数是一个已定义大小的数组 2.3 形式参数是一个未定义大小的数组 2.4 实例演示 1. 二维…

Spring中关于事务的一些方方面面

事务隔离级别: 先了解一些事务隔离级别有哪些: 未提交读(Read Uncommitted): 允许脏读,也就是可能读取到其他会话中未提交事务修改的数据 提交读(Read Committed): 只能读取到已经提交的数据。Oracle等多数数据库默…

组态软件在物联网中的应用

随着物联网的快速发展,组态软件在物联网中的应用也越来越广泛。组态软件是一种用于创建和管理物联网系统的可视化工具,它能够将传感器、设备和网络连接起来,实现数据的采集、分析和可视化。本文将探讨组态软件在物联网中的应用,并…

通信入门系列——双边带信号、单边带信号、Hilbert变换

微信公众号上线,搜索公众号小灰灰的FPGA,关注可获取相关源码,定期更新有关FPGA的项目以及开源项目源码,包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 本节目录 一、双边带信号 二、单边…

详细分析Pandas中的Series对象(附Demo)

目录 1. 问题所示2. 基本知识3. API Demo4. 示例Demo5. 彩蛋 1. 问题所示 从实战上手基础知识 一开始遇到这个Bug: TypeError: unsupported operand type(s) for -: str and float后面经了解执行减法运算时发生了错误,其中一个操作数是字符串类型&…

文献速递:GAN医学影像合成--用生成对抗网络生成 3D TOF-MRA 体积和分割标签

文献速递:GAN医学影像合成–用生成对抗网络生成 3D TOF-MRA 体积和分割标签 01 文献速递介绍 深度学习算法在自然图像分析中的成功近年来已被应用于医学成像领域。深度学习方法已被用于自动化各种耗时的手动任务,如医学图像的分割和分类(G…

React18源码: Fiber树的初次创建过程图文详解

fiber树构造(初次创建) fiber树构造的2种情况: 1.初次创建 在React应用首次启动时,界面还没有渲染此时并不会进入对比过程,相当于直接构造一棵全新的树 2.对比更新 React应用启动后,界面已经渲染如果再次发…

Java 过滤器深入了解学习

Java 过滤器深入了解学习 生活不能等待别人来安排,要自己去争取和奋斗;而不论其结果是喜是悲,但可以慰藉的是,你总不枉在这世界上活了一场。有了这样的认识,你就会珍重生活,而不会玩世不恭;同时…

【服务发现--service】

1、service的定义 "Service"简写"svc”。Pod不能直接提供给外网访问,而是应该使用service。Service就是把Pod暴露出来提供服务,Service才是真正的“服务”,它的中文名就叫“服务”。可以说Service是一个应用服务的抽象&#…

【软考中级】系统集成项目管理工程师—导学

软考中级——系统集成项目管理工程师 原视频链接:2024年05月【持续更新】最新系统集成项目管理工程师培训课程-网络课程-软考中级培训 考试介绍 基础介绍 软考全称又叫计算机技术与软件专业技师资格水平考试。 软考是国家人力资源和社会保障部、工业和信息化部…

基于SpringBoot实现的医院药品管理系统

一、系统架构 前端:html | layui | js | css 后端:springboot | mybatis-plus 环境:jdk1.6 | mysql | maven 二、代码及数据库 三、功能介绍 01. 登录页 02. 药品库存管理-登记出入口信息 03. 药品库存管理-问题药品信息 …

【机器学习科学库】全md文档笔记:Jupyter Notebook和Matplotlib使用(已分享,附代码)

本系列文章md笔记(已分享)主要讨论人工智能相关知识。主要内容包括,了解机器学习定义以及应用场景,掌握机器学习基础环境的安装和使用,掌握利用常用的科学计算库对数据进行展示、分析,学会使用jupyter note…

字符串(算法竞赛)--Manacher(马拉车)算法

1、B站视频链接&#xff1a;F05 Manacher(马拉车)_哔哩哔哩_bilibili 题目链接&#xff1a;【模板】manacher - 洛谷 ​ #include <bits/stdc.h> using namespace std; const int N3e7; char a[N],s[N]; int d[N];//回文半径函数void get_d(char*s,int n){d[1]1;for(int…

SpringBoot:数据访问-整合 Druid 配置数据源监控

点击查看数据访问demo&#xff1a;LearnSpringBoot06DataJdbc 点击查看更多的SpringBoot教程 简介 Druid Spring Boot Starter 用于帮助你在Spring Boot项目中轻松集成Druid数据库连接池和监控。 一、添加druid-spring-boot-starter依赖 点击查询最新版 <dependency&g…

猜字谜|构建生成式 AI 应用实践(一)

在 2023 亚马逊云科技 re:Invent 之后&#xff0c;细心的开发者们也许已经发现有一个很有趣的动手实验&#xff1a;开发一款可部署的基于大语言模型的字谜游戏&#xff1a; 该款游戏使用了文生图模型为玩家提供一个未知的提示词&#xff0c;玩家需要根据模型生成的图像来猜测该…

【基于Ubuntu20.04的Autoware.universe安装过程】方案二:双系统 | 详细记录 | 全过程图文 by.Akaxi

目录 一、Autoware.universe背景 Part-1&#xff1a;安装双系统教程 二、查看Windows引导方式 三、制作安装盘 四、设置电脑配置 1.关闭bitlocker 2.压缩硬盘分区 3.关闭Secure Boot 4.关闭intel RST 5.BIOS设置U盘引导 五、安装Ubuntu20.04 1.ventoy引导 2.安装配…

代码随想录算法训练营Day27 || leetCode 93.复原IP地址 || 78.子集 || 90.子集II

93.复原IP地址 与分割回文串的代码相近&#xff0c;先写出判断函数&#xff0c;之后以判断结果为标准&#xff0c;执行回溯的代码。此题中使用点的个数来决定回溯的终止&#xff0c;需要学习一下。 class Solution { private:vector<string> result;bool isValid(const …

c语言经典测试题5

1.题1 t0; while(printf("*")) { t; if (t<3) break; }关于上述代码描述正确的是&#xff1f; A: 其中循环控制表达式与0等价 B: 其中循环控制表达式与0等价 C: 其中循环控制表达式是不合法的 D: 以上说法都不对 我们来分析一下&#xff1a;printf的返回值…

一个具有强大PDF处理能力的.Net开源项目

PDF具有跨平台、可读性强、不可修改性、无需特定阅读软件、内容安全等好处&#xff0c;在工作中经常都会用到。 所以&#xff0c;我们在项目开发中&#xff0c;经常需要生成PDF的文件&#xff0c;或者把Html、Xml等文件转化为PDF格式。 今天给大家推荐一个具有PDF处理能力的.…

消息队列-RabbitMQ:延迟队列、rabbitmq 插件方式实现延迟队列、整合SpringBoot

十六、延迟队列 1、延迟队列概念 延时队列内部是有序的&#xff0c;最重要的特性就体现在它的延时属性上&#xff0c;延时队列中的元素是希望在指定时间到了以后或之前取出和处理&#xff0c;简单来说&#xff0c;延时队列就是用来存放需要在指定时间被处理的元素的队列。 延…