【C】链表算法题7 -- 环形链表||

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


问题描述 

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


示例1

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


示例2

输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点


思路

  这道题可以沿用上一个环形链表的思想(快慢指针法),上一篇文章中证明了如果链表中有环,那么 fast 指针与 slow 指针一定可以在环中相遇,而在有环链表中还有一个结论,那就是相遇节点与头节点每次都走一步,他们必然会在入环处相遇(证明在代码之后)。

  有了这个结论之后,这道题就很好解决了,我们只需要先判断链表是否有环(上一个环形链表算法题),如果没有环,那么就返回NULL;如果有环,那么找到相遇节点 interNode 之后,然后定义一个节点指针 pcur 指向头节点,如果 pcur 与 interNode 不相同,那么就让 pcur 与interNode 同时往后走,直到他们两相等为止,入环的第一个节点即为 pcur


代码1

 typedef struct ListNode ListNode;//相交结点ListNode* IntersectionNode(ListNode* head){ListNode* slow = head, * fast = head;while (fast && fast->next){slow = slow->next;fast = fast->next->next;if (slow == fast){return slow;}}return NULL;}//入环的第一个节点
struct ListNode *detectCycle(struct ListNode *head) 
{//先找相交节点ListNode* interNode = IntersectionNode(head);if (interNode == NULL){return NULL;}//相遇节点与首结点每次走一步可以在入环处相遇ListNode* pcur = head;while (pcur != interNode){interNode = interNode->next;pcur = pcur->next;}return interNode;
}

 代码2

  当然,上述代码还可以改进一下。不难发现,其实 fast 与 slow 相遇之后,interNode 就是 slow (fast 也可以),所以可以直接用 slow 来作为相遇节点。

typedef struct ListNode ListNode;
struct ListNode *detectCycle(struct ListNode *head) 
{ListNode* fast = head, *slow = head;while (fast && fast->next){slow = slow->next;fast = fast->next->next;if (fast == slow){//相遇了,说明有环ListNode* pcur = head;while (pcur != slow){//相遇节点与首结点每次走一步可以在入环处相遇pcur = pcur->next;slow = slow->next;}return slow;}}return NULL;
}

证明 

  这里将链表抽象为以下结构(假设fast一次走两步,slow一次走一步):

设头节点为H,入环的第一个节点为E,fast 与 slow 相遇节点为M,H 到 E 距离为 L,E 到 M 距离为 X,环的周长为 R,所以 E 到 M 的距离就是 R - X ,再假设 fast 与 slow 相遇之前,fast 已经在环内走了 n 圈了,所以在相遇之前, fast 所走过的路程为:L + nR + X;而 slow 所走过的路程为:L + X,为什么 slow 没有绕环呢,因为在 slow 进入环后,fast 与 slow 的距离是越来越近的,他们俩的最大距离就是环的距离,而他们之间的距离又是越来越近的,所以 fast 是会在 slow 进入环之后的一圈内必然是会追上 slow 的。

  由于 fast 一次走两步,slow 一次走一步,所以 fast 所走的路程是 slow 所成路程的两倍,所以有如下这个等式:

  L + nR + X  = 2 * (L +X)

移项就可以得到:

  nR = L + X    =>   L = nR - X    =>    L =  (n - 1)R + R - X

这个等式也就表明,当 slow 到达相遇节点 M 之后,再绕环走 n - 1 圈,头节点也就到达了与 E 相距 R - X 的节点处;此时,slow 回到相遇点,与 E 的距离也是 R - X。所以相遇节点与头节点每次都走一步,他们必然会在入环处相遇。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/70930.shtml

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

相关文章

uniapp开发h5部署到服务器

1.发行>网站-PC Web或手机H5(仅适用于uniapp) 2.填写网站域名 3.编译成功后会生成一个unpackage文件夹找到下面的h5 4.接下来会使用一个工具把h5里面的文件放到服务器上面(WinSCP使用其他能部署的工具也行) 5.登录 6.登录成功后…

亚信安全正式接入DeepSeek

亚信安全致力于“数据驱动、AI原生”战略,早在2024年5月,推出了“信立方”安全大模型、安全MaaS平台和一系列安全智能体,为网络安全运营、网络安全检测提供AI技术能力。自2024年12月DeepSeek-V3发布以来,亚信安全人工智能实验室利…

小白零基础如何搭建CNN

1.卷积层 在PyTorch中针对卷积操作的对象和使用的场景不同,如有1维卷积、2维卷积、 3维卷积与转置卷积(可以简单理解为卷积操作的逆操作),但它们的使用方法比较相似,都可以从torch.nn模块中调用,需要调用的…

21vue3实战-----git husky和git commit规范

21vue3实战-----git husky和git commit规范 1.husky工具1.1目的1.2如何做到这一点?1.3步骤 2.git commit规范2.1使用Commitizen自动生成规范格式供选择2.2代码提交风格2.3代码提交验证 之前在https://blog.csdn.net/fageaaa/article/details/145474065文章中已经讲了在vue项目…

arduino扩展:Arduino Mega 控制 32 个舵机(参考表情机器人)

参考:表情机器人中使用22个舵机的案例 引言 在电子制作与自动化控制领域,Arduino 凭借其易用性和强大的扩展性备受青睐。Arduino Mega 作为其中功能较为强大的一款开发板,具备丰富的引脚资源,能够实现复杂的控制任务。舵机作为常…

PyQt学习记录03——批量设置水印

0. 目录 PyQt学习记录01——加法计算器 PyQt学习记录02——串口助手 1. 前言 本次主要是为了学习Qt中的 QFileDialog 函数, QFileDialog.getExistingDirectory:用于选择文件夹,返回的是一个文件夹路径。 QFileDialog.getOpenFileName&…

Visual Studio 使用 “Ctrl + /”键设置注释和取消注释

问题:在默认的Visual Studio中,选择单行代码后,按下Ctrl /键会将代码注释掉,但再次按下Ctrl /键时,会进行双重注释,这不是我们想要的。 实现效果:当按下Ctrl /键会将代码注释掉,…

社区版IDEA中配置TomCat(详细版)

文章目录 1、下载Smart TomCat2、配置TomCat3、运行代码 1、下载Smart TomCat 由于小编的是社区版,没有自带的tomcat server,所以在设置的插件里面搜索,安装第一个(注意:安装时一定要关闭外网,小编因为这个…

Flink-DataStream API

一、什么样的数据可以用于流式传输 Flink的DataStream API 允许流式传输他们可以序列化的任何内容。Flink自己的序列化程序用于 基本类型:即字符串、长、整数、布尔值、数组复合类型:元组、POJO和Scala样例类 基本类型我们已经很熟悉了,下…

渗透利器:Burp Suite 联动 XRAY 图形化工具.(主动扫描+被动扫描)

Burp Suite 联动 XRAY 图形化工具.(主动扫描被动扫描) Burp Suite 和 Xray 联合使用,能够将 Burp 的强大流量拦截与修改功能,与 Xray 的高效漏洞检测能力相结合,实现更全面、高效的网络安全测试,同时提升漏…

Java 大视界 -- 深入剖析 Java 在大数据内存管理中的优化策略(49)

💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

JVM ②-双亲委派模型 || 垃圾回收GC

这里是Themberfue 在上节课对内存区域划分以及类加载的过程有了简单的了解后,我们再了解其他两个较为重要的机制,这些都是面试中常考的知识点,有必要的话建议背出来,当然不是死记硬背,而是要有理解的背~~~如果对 JVM …

html文件怎么转换成pdf文件,2025最新教程

将HTML文件转换成PDF文件,可以采取以下几种方法: 一、使用浏览器内置功能 打开HTML文件:在Chrome、Firefox、IE等浏览器中打开需要转换的HTML文件。打印对话框:按下CtrlP(Windows)或CommandP(M…

2025 西湖论剑wp

web Rank-l 打开题目环境: 发现一个输入框,看一下他是用上面语言写的 发现是python,很容易想到ssti 密码随便输,发现没有回显 但是输入其他字符会报错 确定为ssti注入 开始构造payload, {{(lipsum|attr(‘global…

Web前端开发--HTML

HTML快速入门 1.新建文本文件&#xff0c;后缀名改为.html 2.编写 HTML结构标签 3.在<body>中填写内容 HTML结构标签 特点 1.HTML标签中不区分大小写 2.HTML标签属性值中可以使用单引号也可使用双引号 3.HTML语法结构比较松散&#xff08;但在编写时要严格一点&…

网络工程师 (30)以太网技术

一、起源与发展 以太网技术起源于20世纪70年代&#xff0c;最初由Xerox公司的帕洛阿尔托研究中心&#xff08;PARC&#xff09;开发。最初的以太网采用同轴电缆作为传输介质&#xff0c;数据传输速率为2.94Mbps&#xff08;后发展为10Mbps&#xff09;&#xff0c;主要用于解决…

ONES 功能上新|ONES Copilot、ONES TestCase、ONES Wiki 新功能一览

ONES Copilot 支持基于当前查看的工作项相关信息&#xff0c;利用 AI 模型&#xff0c;在系统中进行相似工作项的查找&#xff0c;包括基于已关联工作项的相似数据查找。 应用场景&#xff1a; 在查看工作项时&#xff0c;可利用 AI 模型&#xff0c;基于语义相似度&#xff0c…

从 X86 到 ARM :工控机迁移中的核心问题剖析

在工业控制领域&#xff0c;技术的不断演进促使着工控机从 X86 架构向 ARM 架构迁移。然而&#xff0c;这一过程并非一帆风顺&#xff0c;面临着诸多关键挑战。 首先&#xff0c;软件兼容性是一个重要问题。许多基于 X86 架构开发的工业控制软件可能无法直接在 ARM 架构上运行…

《qt open3d网格平滑》

qt open3d网格平滑 效果展示二、流程三、代码效果展示 二、流程 创建动作,链接到槽函数,并把动作放置菜单栏 参照前文 三、代码 1、槽函数实现 void on_actionFilterSmoothSimple_triggered();void MainWindow::on_actionF

Redis 的缓存雪崩、缓存穿透和缓存击穿详解,并提供多种解决方案

本文是对 Redis 知识的补充&#xff0c;在了解了如何搭建多种类型的 Redis 集群&#xff0c;并清楚了 Redis 集群搭建的过程的原理和注意事项之后&#xff0c;就要开始了解在使用 Redis 时可能出现的突发问题和对应的解决方案。 引言&#xff1a;虽然 Redis 是单线程的&#xf…