【链表】环形链表

环形链表

  • 环形链表I
    • 题目
    • 思路讲解
    • 代码书写
    • 拓展问题
  • 环形链表II
    • 题目
    • 题目解析
    • 思路讲解
    • 代码书写

环形链表I

题目

题目链接: 环形链表

思路讲解

对于探究一个线性结构是否有环, 最经典的做法就是快慢指针法. 我们定义两个指针, 一个一次走两步, 一个一次走一步, 走完后判断两个是否相等. 如果能够相遇, 那么就一定有环. 如果无法相遇, 那么快指针一定会先到终点, 此时就没有环.

代码书写

public class Solution {public boolean hasCycle(ListNode head) {ListNode fast = head, slow = head;while(fast != null && fast.next != null){fast = fast.next.next;slow = slow.next;if(slow == fast) return true;}return false;}
}

拓展问题

为什么使用快慢指针法可以探究链表是否有环?

我们可以设想一个场景, 有两个同学在跑1000米. 一个同学跑得快, 一个同学跑的慢, 那么此时就可能会出现一个情况叫做"套圈". 也就是跑的快的人在跑第二圈的过程中, 遇到了还在跑第一圈的跑的慢的人. 如下图所示

在这里插入图片描述

那么此时可能有人就要问了: slow和fast是否可以走更多步?

首先我们来探究 fast 是否可以走更多步这个问题, 假设 slow 依旧是走一步, fast可以走更多步.

如果按照我们上面的理解方法来看, 似乎也是没有问题的. 因为我只要可以套慢的人的圈, 那么我就一定可以发现是有环的. 但是实际上如果从我们的代码上来看, 这是不一定可行的. 为什么呢?

理由是在代码中我们的判断, 都是在走完后来进行的. 也就是说, 如果我在套圈的过程中超过了你, 我此时并不会判定为我们相遇了. 那么此时可能就会产生如下的情况.
在这里插入图片描述

那么是什么导致了 fast 走两步, slow 走一步, 就是可行的呢?

在思考这个问题之前, 我们思考另外一个问题, 为什么上面的三步配合一步是不可行的呢? 我们可以发现, 它实际上就是会使得 fast 会跳过 slow(实际上这里有一个解决办法就是, fast走一步就判断一次, 但我们这里先不谈这种做法)

而此时我们回到 fast 走两步, slow走一步的情况, 我们可以发现, 在这种情况中, fast 相对于 slow, 总是在以 1 步的相对速度逐渐靠近的(fast 走两步, slow 走一步, 相对速度 = fast - slow, 即一步). 而同时我们长度的最低计量单位就是 1 步, 那么此时自然就不可能会发生直接越过 slow 的情况了

那么此时我们就可以得出结论, fast 和 slow 是可以走更多步的, 但是对其速度的要求是相对速度需要为 1.

环形链表II

题目

题目链接: 环形链表 II

题目解析

这一题是上面一题的拓展, 要求是判断链表是否有环, 如果有环, 则返回环的入口. 如果没有环, 则返回null.

思路讲解

首先判断是否有环, 我们使用的是上面一题的快慢指针法. 但是对于环的入口, 我们就需要使用一个新的点来进行寻找.

寻找的方法就是: 当快慢指针相遇后, 让任意指针回到开头, 然后两个指针一步一步的走, 最终相遇的点就是环的入口. 很明显这个做法就是利用了一种等量关系. 即 相遇点到入口的距离 == 起始点到达入口的距离.

下面我们就通过简单的数学方程来推导这个等量关系.

在这里插入图片描述

首先我们要计算出 fast 的路程, 很明显, fast的路程就是 X + n*C + (C - Y)

因为首先 fast 走完 X, 然后一直在里面绕圈, 直到相遇, 其中绕的圈数为 n.

随后就是 slow 走的路程, 此时可能有人就要问了: slow有没有可能绕圈呢? 实际上. slow无论如何都跑不完一圈的. 试想一个最差情况, 如下图所示

在这里插入图片描述

此时 fast 刚过入口, slow 就进来了, 无疑是最差情况, 那么此时 slow 能走完一圈吗? 答案是肯定不能, 为什么?

假设我们的 slow 能够走一圈, 那么此时 fast 的速度既然是 slow 的两倍, 那它理论上都走完了两圈了, 怎么可能会追不上 slow 呢? 因此 slow 最多就只能走 (C - Y) 的路程

此时我们就能够计算出 slow 走的总路程为 X + (C - Y)

随后再根据等量关系, fast 的路程是 slow 的两倍, 我们可以得出 2(X + (C - Y)) = X + n*C + (C - Y)

两边约掉后, 就能够得出等量关系为 X = (n - 1)*C + Y

也就是说, 如果让两个指针同时从相遇点和起始点向入口点出发, 那么其中的一个指针会沿着 X 出发, 而另一个则会先绕 n - 1 圈, 随后在相遇点再走 Y 距离后就会在起始点相遇.

如果这不够直观, 我们可以取 n 为 1, 也就是在 slow 进入圈前, fast只走了一圈, 那么此时就有 X = Y. 此时自然两者同时出发, 同速前进, 就会在入口点相遇了.

代码书写

public class Solution {public ListNode detectCycle(ListNode head) {ListNode fast = head, slow = head;while(fast != null && fast.next != null){fast = fast.next.next;slow = slow.next;if(fast == slow){// 此时有环, 回归起点, 同速前进fast = head;while(fast != slow){slow = slow.next;fast = fast.next;}return fast;}}// 此时无环return null;}
}

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

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

相关文章

虚幻引擎VR游戏开发01 | VR设备和术语

四款Unreal Engine默认配套按键映射的VR设备 IMC按键映射 Oculus Touch (R) Grip Axis: 代表Oculus Rift或Quest设备的右手控制器的抓握轴输入。Valve Index (R) Grip Axis: 代表Valve Index设备的右手控制器的抓握轴输入。Vive (R) Grip: 代表HTC Vive设备的右手控制器的抓握…

chrome 插件开发入门

1. 介绍 Chrome 插件可用于在谷歌浏览器上控制当前页面的一些操作,可自主控制网页,提升效率。 平常我们可在谷歌应用商店中下载谷歌插件来增强浏览器功能,作为开发者,我们也可以自己开发一个浏览器插件来配合我们的日常学习工作…

Vite - 兼容旧版浏览器 plugin-legacy(2)

目录 1,问题2,解决3,String 其他新增 API 的版本 接上文 Vite - 兼容旧版浏览器 plugin-legacy(1) 1,问题 客户浏览器报错,不支持 replaceAll 方法。 该方法在 query-string 依赖内部使用了。…

嵌入式Linux:常见信号的默认行为

信号是一种软件中断,用于通知进程发生了某种异步事件。信号可以由用户、其他进程或操作系统内核产生。进程可以选择捕获并处理这些信号,或者忽略它们,让系统执行默认操作。 不可靠信号(非实时信号):编号为 …

反爬虫策略收录集

前言 反爬虫,是指对扫描器中的网络爬虫环节进行反制,通过一些反制策略来阻碍或干扰爬虫的正常爬行,从而间接地起到防御目的。下面是一些常见的反爬虫策略的收录。 入门版 封IP 由于服务器有防火墙(如果防火墙在TCP/UDP层或者它…

渲染100高性能云渲染,性价比超高

在这个3D渲染行业迅速发展的时代,对于渲染速度和稳定性的渴望日益强烈。需要更快的渲染时间来缩短项目周期,同时希望渲染过程更加稳定,避免问题导致的损失。 如今市场上虽然不乏各种云渲染服务,但要找到既经济又能满足高要求的选…

Java内存区域

文章目录 运行时数据区域1. 程序计数器2. 虚拟机栈局部变量表 3. 本地方法栈4. 堆5. 方法区运行时常量池直接内存 运行时数据区域 Java虚拟机在执行Java程序的过程中会把它管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间&…

sqli-labs靶场通关攻略(61-65)

Less-61 步骤一:查看数据库 ?id1)) and updatexml(1,concat(1,(select database())),1)-- 步骤二:查看表名 ?id1)) and updatexml(1,concat(1,(select group_concat(table_name) from information_schema.tables where table_schemasecurity)),1)--…

uniapp写的一个年月日时分秒时间选择功能

代码: <template><view><picker mode"multiSelector" :value"multiIndex" :range"multiRange" change"onMultiChange"><view class"picker">当前选择&#xff1a;{{ formattedDateTime }}</vie…

中国各地级市的海拔标准差

海拔标准差是衡量地理测量准确性的重要指标&#xff0c;它通过计算特定地点的海拔测量值与平均海拔之间的偏差来评估数据的可靠性。较小的标准差意味着测量结果较为一致&#xff0c;而较大的标准差则可能指出数据的波动性或测量误差。 计算方法 海拔标准差的计算遵循以下公式…

C++学习/复习补充记录 --- 图论(深搜,广搜)

图的度 无向图&#xff1a; 连接某节点的边数&#xff0c;即为该节点的【度】。 &#xff08;无向图中&#xff0c;有5条边连接节点4&#xff0c;则节点4的度为5。&#xff09; 有向图&#xff1a; 出度&#xff1a;从该节点出发的边的个数。 入度&#xff1a;指向该节点边的个…

Idea_服务器自动化部署_傻瓜式教程

使用Alibaba Cloud Toolkit 在 IntelliJ IDEA 中一键部署项目到服务器 1. 安装 Alibaba Cloud Toolkit 插件 确保 IntelliJ IDEA 版本为 2018.3 或以上。打开 IntelliJ IDEA&#xff0c;进入 File -> Settings -> Plugins&#xff0c;搜索并安装 Alibaba Cloud Toolkit…

【Python基础】字典类型

本文收录于 《Python编程入门》专栏&#xff0c;从零基础开始&#xff0c;分享一些Python编程基础知识&#xff0c;欢迎关注&#xff0c;谢谢&#xff01; 文章目录 一、前言二、Python 字典类型2.1 访问字典里的值2.2 修改字典2.3 删除字典元素2.4 字典键值的特性2.5 遍历字典…

Vision Transformer (ViT) + 代码【详解】

文章目录 1、Vision Transformer (ViT) 介绍2、patch embedding3、代码3.1 class embedding Positional Embedding3.2 Transformer Encoder3.3 classifier3.4 ViT总代码 1、Vision Transformer (ViT) 介绍 VIT论文的摘要如下&#xff0c;谷歌翻译如下&#xff1a; 虽然 Transf…

《JavaEE进阶》----10.<SpringMVC应用分层:【三层架构】>

本篇博客我们主要讲解 1.应用的分层&#xff1a;三层架构 2.Spring MVC和三层架构的区别和联系 3.软件设计原则&#xff1a;高内聚低耦合 4.应用分层的好处 5.通过应用分层后的代码示例 一、三层架构简介 阿里开发手册中,关于工程结构部分,定义了常见工程的应用分层结构: 上图…

【Java 基础】:三大特征之多态

✨ 杏花疏影里&#xff0c;吹笛到天明 &#x1f30f; &#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;java学习 ⛺️ 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&…

u盘格式化数据还能恢复吗?点击了解实用教程

U盘是电子数据存储设备&#xff0c;我们主要用它来转移数据、随身携带数据等。同时U盘在使用过程中常会遇到问题&#xff0c;比如U盘中毒&#xff0c;U盘中毒会导致里面保存的数据文件无法读取&#xff0c;我们需要进行U盘格式化。格式化之后的U盘才可以继续使用&#xff0c;那…

软件测试-Selenium+python自动化测试

目录 会用到谷歌浏览器Chrome测试,需要下载一个Chromedriver(Chrome for Testing availability)对应自己的浏览器版本号选择。 一、元素定位 对html网页中的元素进行定位,同时进行部分操作。 1.1一个简单的模板 from selenium import webdriver from selenium.webdrive…

本地部署AList并挂载小雅超集结合内网穿透实现无公网IP远程访问

文章目录 前言1. 本地部署AList2. AList挂载网盘3. 部署小雅alist3.1 Token获取3.2 部署小雅3.3 挂载小雅alist到AList中 4. Cpolar内网穿透安装5. 创建公网地址6. 配置固定公网地址 &#x1f4a1; 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff…

42.接雨水

42.接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1…