力扣——环形链表问题

ops/2024/10/23 14:11:45/

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

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

前言

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

判断链表是否有环

给定一个链表,判断链表中是否有环。OJ链接
环形<a class=链表" />
方法:快慢指针
思路:

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

代码如下:

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.ppmy.cn/ops/127834.html

相关文章

昂辉科技与您相约2024芜湖新能源汽车零部件博览会

尊敬的先生/女士&#xff1a; 我们诚挚邀请您参加10月14日至10月17日&#xff0c;在安徽省芜湖市宜居国际博览中心召开的2024芜湖新能源汽车零部件和后市场生态博览会。本次展会汇聚了来自政府、行业机构、高校院所及企业的众多代表&#xff0c;旨在构建集展示、交流、交易于一…

【Flutter】Dart:Isolate

在 Dart 和 Flutter 中&#xff0c;所有的代码默认都运行在单一的线程&#xff08;即主线程&#xff09;上&#xff0c;这个线程也叫做 UI 线程。当进行耗时操作&#xff08;如复杂计算或网络请求&#xff09;时&#xff0c;如果不使用多线程处理&#xff0c;主线程会被阻塞&am…

数据结构——笛卡尔树详解

数据结构——笛卡尔树 1&#xff0c;笛卡尔树的介绍2&#xff0c;笛卡尔树的构建3&#xff0c;笛卡尔树的代码实现 1&#xff0c;笛卡尔树的介绍 前面我们讲过《堆》和《二叉搜索树》&#xff0c;能不能把这两种数据结构的特性结合起来构造一棵新的树呢&#xff1f;当然是可以…

离散制造和流程制造分别是什么?它们有什么区别?

为何有的企业生产过程看似一气呵成&#xff0c;而有的则是由多个环节组合而成&#xff1f;其实这就涉及到了制造业的两种常见生产模式。 流程制造离散制造 那么&#xff0c;在生产管理方面&#xff0c;离散制造和流程制造分别有什么特点、区别呢&#xff1f; 今天&#xff0…

Linux——应用软件的生命周期

功能开发测试&#xff1a; 功能性测试 对应开发框架的测试用例代码的漏洞扫描 Web服务器版本应用开发语言的依赖关系和版本信息是否会造成类似内存泄露等影响系统性能的问题压力测试应用的部署 获取应用代码以及应用静态文件的代码包将安装包中的文件按照服务器配置的架构&…

sql-labs靶场第十九关测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、寻找注入点 2、注入数据库 ①寻找注入方法 ②爆库&#xff0c;查看数据库名称 ③爆表&#xff0c;查看security库的所有表 ④爆列&#xff0c;查看users表的所有列 ⑤成功获取用户名…

webAPI中的offset、client、scroll

一、元素偏移量offset 1.offset概述 offset翻译成中文叫&#xff1a;偏移量&#xff0c;我们使用offset系列相关属性可以动态的得到该元素的位置&#xff08;偏移&#xff09;、大小等等 获得元素距离带有定位父元素的位置获得元素自身的大小&#xff08;宽度和高度&#xf…

Python 爬虫实战与技巧分享--urllib

Python 爬虫实战与技巧分享–urllib 在当今信息时代&#xff0c;数据的价值日益凸显。Python 爬虫作为一种强大的数据获取工具&#xff0c;能够帮助我们从互联网上抓取各种有价值的信息。本文将结合具体代码示例&#xff0c;深入探讨 Python 爬虫的相关知识和关键要点。 一、…