代码随想录二刷 | 链表 |环形链表II

代码随想录二刷 | 链表 |环形链表II

  • 题目描述
  • 解题思路 & 代码实现
    • 判断链表是否有环
    • 如何找到环的入口

题目描述

142.环形链表II

给定一个链表的头节点 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
解释:链表中没有环。

提示:

链表中节点的数目范围在范围 [0, 104] 内
-105 <= Node.val <= 105
pos 的值为 -1 或者链表中的一个有效索引

进阶:你是否可以使用 O(1) 空间解决此题?

解题思路 & 代码实现

本题主要解决两个问题:

  • 判断链表是否有环
  • 如果有环如何找到环的入口

判断链表是否有环

使用快慢指针法,分别定义fastslow两个指针,从头节点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果两个指针在途中相遇,说明这个链表有环。

强调途中的意思是指两个指针不是在链表末尾相遇的。

因为fast指针移动的快,所以如果两个指针相遇,一定是fast追上了slow指针,并且一定是在环中相遇,因为假如不在环中相遇,fast是无法从slow的后面追上slow的。

至于fast为什么走两步,slow为什么走一步,是因为如果存在环,fast相当于是一步一步的追赶slow,也可以想象为slow没有动,fast一次走一步,这样就比较好理解了。

之所以slow也要移动,是因为最终要找的是环的入口,slow如果不移动,环的入口就比较难判断。

如何找到环的入口

假设从头结点到环形入口节点的节点数为x。 环形入口节点到 fast指针与slow指针相遇节点节点数为y。 从相遇节点再到环形入口节点节点数为z。 如图所示:

在这里插入图片描述
相遇时,slow指针走过的路程为x + y,fast针走过的路程为x + y + n * (y + z)n表示fast指针在环内走了 n 圈才遇到slow指针。

因为fast指针的速度是slow指针的两倍,fast指针走的路程是slow指针走的路程的两倍:

x + y + n * (y + z) = 2 * (x + y)

因为要求的是环形入口节点的位置,因此把 x 放在等式左边:

x = n * (y + z) - y

再从其中提取出一个 y + z来:

x = (n - 1) (y + z) + z

n = 1时,也就是fast指针只走了一圈时,公式可化简为x = z,这表示如果从头节点出发一个指针,从相遇节点也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候,那个相遇的节点就是环形入口节点。

n > 1的时候,由于y + z就是环的长度,这表示fast指针在圈内走了一些圈数,最终还是能得出n = 1时的结论。

class Solution{
public:ListNode* detectCycle(ListNode* head){ListNode* fast = head;ListNode* slow = head;while (fast != NULL && fast -> next != NULL) {slow = slow -> next; // slow移动一步fast = fast -> next -> next; // fast移动两步if (slow == fast) { // 当 fast 和 slow 相遇时ListNode* curA = head;ListNode* curB = fast;while (curA != curB) {curA = curA -> next;curB = curB -> next;}return curA; // 找到入口节点}}return NULL:}
};

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

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

相关文章

基于Vue3的低代码开发平台——JNPF

目录 一、什么是Vue.js &#xff1f; 二、Jnpf-Web-Vue3 的技术栈介绍 &#xff08;1&#xff09;Vue3.x &#xff08;2&#xff09;Vue-router4.x &#xff08;3&#xff09;Vite4.x &#xff08;4&#xff09;Ant-Design-Vue3.x &#xff08;5&#xff09;TypeScript &#x…

Java的判空

校验List 在进行参数非空校验时&#xff0c;我们总是容易直接就对任何的东西都来一个&#xff01; null 其实这样并不完全正确&#xff0c;对list类型来说 不等于null和list.size ! 0是不一样的。 不等于null是指已经声明了list的存在&#xff0c;并且在堆内存中有了引用。 …

Linux设置静态IP

Linux设置静态IP 使用ip addr查看ip&#xff0c;如下所示就是动态IP 1、什么是静态IP&#xff1f; 静态ip就是固定的ip&#xff0c;需要手动设置。静态IP地址&#xff08;又称固定IP地址&#xff09;是长期分配给一台计算机或网络设备使用的 IP 地址。一般来说&#xff0c;一…

低代码平台选型宝典:避免弯路,轻松选对适合你的平台

当前&#xff0c;低代码技术正值热门时期&#xff0c;众多低代码平台产品如雨后春笋般涌现&#xff0c;令人目不暇接。对于软件公司或企业IT部门的负责人来说&#xff0c;如何在这繁花似锦的市场中&#xff0c;精准选中适合自身需求的低代码平台&#xff0c;无疑是一项重要而棘…

java:application.properties的详细使用以及区分环境

文章目录 什么是application.properties文件&#xff1f;如何在Java中使用application.properties文件&#xff1f;将数据注入到 Bean 中使用自定义的配置文件使用命令行参数进行配置配置文件的优先级加载外部的配置文件多环境配置1、创建配置文件2、在 application.properties…

基于springboot实现“漫画之家”系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现“漫画之家”系统演示 摘要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&am…

自学成为android framework高手需要准备哪些装备-千里马车载车机系统开发学习

背景 hi&#xff0c;粉丝朋友们&#xff1a; 大家好&#xff01;经常有很多学员买课同学都会问到需要准备哪些装备&#xff0c;我也回答了很多学员了&#xff0c;今天就搞一篇文章来统一说明一下&#xff0c;告诉一下大家如果你想从一个framework新手变成一个framework开发的高…

【Java】实现阻塞队列-生产者/消费者模型

上文中我们讲了Java库中自带的阻塞队列&#xff0c;并且讲了如何用阻塞队列来实现生产者消费者模型 【Java】用Java库中自带的阻塞队列以及用阻塞队列实现生产者-消费者模型 下面我们来讲如何用代码实现一个阻塞队列 1、实现一个阻塞队列 阻塞队列 普通队列 线程安全 阻…

编译源码-【opencv3.4.16 + vs2013 x64】

编译机器&#xff1a;i5 13500HX RTX 4050 laptop win11 CMake 3.26.4 Configure&#xff0c;去掉勾选图中黄色标注的项&#xff0c;opencv_world 随意 Configure可能提示3rdparty下载timeout&#xff0c;它会下载到源码目录的.cache ├── .cache │ ├──ffmpeg │ │ …

易点易动设备管理系统:提升企业设备保养效率的最佳选择

在现代企业中&#xff0c;设备的正常运行和保养对于业务的顺利进行至关重要。然而&#xff0c;传统的手动设备管理方式往往效率低下、容易出错&#xff0c;给企业带来不必要的成本和风险。为了解决这一问题&#xff0c;易点易动设备管理系统应运而生。本文将介绍易点易动设备管…

【操作系统】I/O软件层次结构

文章目录 1. 前言2. I/O软件层次结构2.1 用户层软件2.2 设备独立性软件2.3 设备驱动程序2.4 中断处理程序 1. 前言 偶然看到“程序员的护城河是什么”这个话题&#xff0c;作为一个工作两年多的程序员吧&#xff0c;经常看到网上关于各种35岁危机、裁员甚至猝死之云云。最近也…

数据结构题型

选择题 2021 数据处理的单位&#xff1a;数据元素 矩阵压缩存储 2022 ①单链表头插法选择 ②矩阵压缩存储&#xff0c;行优先 ③删除链表节点的时间复杂度 ④稀疏矩阵存储 ⑤平衡二叉树时间复杂度 ⑥栈和队列的出队&#xff0c;问栈的大小至少多少 ⑦拓扑排序 ⑧参考书 360…