【LeetCode】带环链表两道题
第一题:环形链表
问题介绍
给你一个链表的头节点head
,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪next
指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos
不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回true
。 否则,返回false
。
问题设置:
- 链表中节点的数目范围是
[0, 10^4]
-10^5 <= Node.val <= 10^5
pos
为-1
或者链表中的一个有效索引
。
问题解释:
问题的函数接口传过来的是不带哨兵位的单链表。
可以使用快慢指针来解决。先让快指针和慢指针都指向链表的起始结点,快指针一次走两步,慢指针一次走一步。
如果是带环链表,快指针先进环,慢指针后进环,就成了追及问题。
如果不是带环链表,快指针会走到空,此时结束。
一些问题分析
-
那为什么快指针一次走两步,慢指针一次走一步,快指针就一定能在环内追上慢指针,和慢指针相遇呢?
当快慢指针都进环后,
最好的情况是,慢指针一进环,就和快指针相遇,程序就结束。
最坏的情况是,慢指针一进环,快指针在慢指针的前一个位置。
假设环内的结点数为N,此时快指针和慢指针相差了N-1步,
因为快指针一次走两步,慢指针一次走一步,每次快指针都比慢指针多走一步,(N-1)的差值会不断减1,直到减为0。
所以慢指针走N-1步后,快指针就会追上慢指针和慢指针相遇。
可以发现:在慢指针进环后,快指针一定可以在慢指针走完一圈之前追上慢指针和慢指针相遇。 -
那为什么一定是快指针一次走两步,慢指针一次走一步才行,快指针一次走三步,走四步等等不行吗?
首先快指针一次走的步数如果大于两步,循环结束的判断条件会更不好控制是一方面;
同时,像上一个问题分析的,如果慢指针进环后,快指针和慢指针的差距步是N-1,
当快指针一次走三步,慢指针一次走一步,快指针和慢指针每走一次,差距步就缩减两步。
如果N是奇数的情况下,N-1是偶数,(N-1)不断以两步的速度缩减,最终会减为0,也就是快指针追上慢指针和慢指针相遇了
但如果N是偶数的情况下,N-1是奇数,(N-1)不断以两步的速度缩减(也就是:N-1,N-3,…,3,1,-1);差距步并不能减为0,也就是快指针能追上慢指针,但会和慢指针擦肩而过,直到差距步减为-1的情况出现,快指针又恰好处于慢指针的前一个位置,差距步又恢复为N-1,这就导致在某些极端场景下,出现快指针永远追不上慢指针的问题。
快指针一次走四步等情况,也是类似的道理,就不再赘述。
如果你非要抬杠说,让快指针一次走三步,慢指针一次走两步,进环后差距步也是每次缩减1步,快指针最后也会追上慢指针并和慢指针相遇,不是吗?
那我只能说:对对对,你说得对!
参考代码
bool hasCycle(struct ListNode* head)
{struct ListNode* slow=head;struct ListNode* fast=head;//因为fast一次走两步,所以需要同时判断fast和fast->next是不是NULLwhile(fast!=NULL&&fast->next!=NULL){slow=slow->next;fast=fast->next->next;if(slow==fast){return true;}}return false;
}
第二题:环形链表 II
问题介绍
给定一个链表的头节点head
,返回链表开始入环的第一个节点。如果链表无环,则返回null
。
如果链表中有某个节点,可以通过连续跟踪next
指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。如果pos
是-1
,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改链表。
问题设置
链表中节点的数目范围在范围[0, 10^4]
内
-10\^5 <= Node.val <= 10\^5
pos
的值为-1
或者链表中的一个有效索引
问题解释
这道题相较上一道题,需要返回带环链表的入环结点。
问题的函数接口传过来的也是不带哨兵位的单链表。
解决这道题需要画图和进行简单的数学分析
假设H为链表的起始点,E为入口点,M为相遇点,
H到E的距离为L,环的大小为R,E到M的距离为X,则M到E的距离为R-X
当快指针和慢指针在M点相遇时,
慢指针走过的距离是:L+X;
快指针走过的距离是:L+n*R+X(n>=1);
在第一题中已经分析:
最好的情况是,慢指针一进环,就和快指针相遇,程序就结束,
此时对于快指针来说,n恰好是1;
最坏的情况是,慢指针一进环,快指针在慢指针的前一个位置,
此时慢指针需要走N-1步,快指针自然要走2倍的N-1步,快指针如果想追上慢指针,就必须先到达入口点E,最终n也可以说是大于等于1的。
但是,这样说未免有失偏颇。
当L很短,而R很大的时候,上述情况可能还说得过;
但如果L很长,R很小,在慢指针还未入环的时候,快指针已经在环内跑了好几圈,这就是另一种情况了。
所以可得出n是大于等于1的。
有了上述的铺垫,可以列出数学等式:
2(L+X) = L+nR+X
=> L+X = nR = (n-1)*R+R
=> L= (n-1)R+R-X
这说明什么呢?
也就是说,有两个指针,一个从H点出发,一个从M点出发,当他们相遇时,他们共同所指的结点就是带环链表的入环结点。
是不是很神奇,下面用代码验证一下吧。
参考代码
struct ListNode* detectCycle(struct ListNode* head)
{struct ListNode* slow=head;struct ListNode* fast=head;while(fast!=NULL&&fast->next!=NULL){slow=slow->next;fast=fast->next->next;//找到相遇点if(slow==fast){struct ListNode* cur1=head;struct ListNode* cur2=slow;while(cur1!=cur2){cur1=cur1->next;cur2=cur2->next;}return cur1;}}return NULL;
}
相关文章:

【LeetCode】带环链表两道题
第一题:环形链表 问题介绍 给你一个链表的头节点head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪next指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数pos 来表示链表…...

CSS奇思妙想之-利用CSS裁剪(clip-path)完成各种图形
在日常开发当中,如果想要开发多边形,一般都需要多个盒子或者伪元素的帮助,有没有一直办法能只使用一个盒子实现呢? 有的:css裁剪 clip-path介绍 css裁剪(clip-path)这个属性平时率非常低。但是…...
力扣每日一题刷题总结:哈希表篇
剑指 Offer II 033.变位词组 Medium 哈希表 变位词 2023/3/3 给定一个字符串数组 strs ,将 变位词 组合在一起。 可以按任意顺序返回结果列表。 注意:若两个字符串中每个字符出现的次数都相同,则称它们互为变位词。 示例: 示例 1:…...

【Redis】redis大key和大value的危害,如何处理?
前序 还记得上次和同事一起去面试候选人时,同事提了一个问题:Redis的大key有什么危害?当时候选人主要作答的角度是一个key的value较大时的情况,比如: 内存不均:单value较大时,可能会导致节点之…...
Spring Boot:实现MyBatis动态创建表
在有些应用场景中,我们会有需要动态创建和操作表的需求。 比如因为单表数据存储量太大而采取分表存储的情况,又或者是按日期生成日志表存储系统日志等等。这个时候就需要我们动态的生成和操作数据库表了。 而我们都知道,以往我们使用MyBati…...

SpringBoot+Seata在多数据源和feign中的简单使用
SpringBootSeata简单使用 目录seata执行过程安装seata下载seata使用自定义配置文件,NACOS为注册中心结合springboot实现AT模式1.多数据源引入依赖bootstrap.yml配置在使用的方法上用GlobalTransactional注解调用接口正常时调用接口报错时回滚2.配合feignseata优缺点seata执行过…...

计算机网络中的原码、反码、补码
写在前面 原码、反码、补码是计算机组成原理中的概念,是计算机网络的基础知识之一。这些概念是为了处理二进制数的符号位而引入的,常用于计算机中的整数运算,也常用于数据存储和传输等领域。因此,了解和掌握这些概念对于理解计算机…...
七、Bean的实例化方式
Spring为Bean提供了多种实例化方式,通常包括4种方式。(也就是说在Spring中为Bean对象的创建准备了多种方案,目的是:更加灵活) 第一种:通过构造方法实例化第二种:通过简单工厂模式实例化第三种&…...

Windows程序员学习Linux环境下VI(VIM)编辑器的使用方法
我是荔园微风,作为一名在IT界整整25年的老兵,今天我们来重新审视一下Windows程序员如何学习Linux环境知识。由于很多程序在Windows环境下开发好后,还要部署到Linux服务器上去,所以作为Windows程序员有必要学习Linux环境的知识。VI…...
react入门篇
react入门篇前言一、目标二、项目环境三、实现过程(干货满满💥💥💥)1.创建react项目2.arco design UI库3.路由模块化4. 状态管理zustand5. axios6. 路由守卫前言 提示:这里可以添加本文要记录的大概内容&a…...

阿赵的MaxScript学习笔记分享九《可编辑多面体的操作》
大家好,我是阿赵。这是MaxScript学习笔记分享的第九篇,可编辑多面体的操作。不知不觉写了这么多篇了,应该还有几篇就写完了。自己给自己加一下油。 在3DsMax里面如果需要建模,一般使用到的塌陷方式有3种,可编辑的网格、…...

【Redis场景5】集群秒杀优化-分布式锁
集群环境下的秒杀问题 前序 【Redis场景1】用户登录注册 【Redis场景2】缓存更新策略(双写一致) 【Redis场景3】缓存穿透、击穿问题 【Redis场景拓展】秒杀问题-全局唯一ID生成策略 【Redis场景4】单机环境下秒杀问题 在单机环境下的并发问题,我们可以使用相关…...

transformer目标检测开山之作detr
1. 将一个batch的图片输入backone获得feature。 (2,c,w,h)先输入resnet50中,得到(2,2048,w,h)。虽然这里channel不是256,但是在输入e…...

双指针法|位运算|离散化|区间合并
目录 双指针算法 位运算 离散化 序列合并 双指针算法 题目描述:1.输入n个单词,每个单词在输入的时候按空格隔开,之后打印出每个单词且换行 #include<iostream> #include <string>using namespace std; int main() {strin…...

Rockchip Android13 GKI开发指南
Rockchip Android13 GKI开发指南 文章目录Rockchip Android13 GKI开发指南GKI介绍Google upstream kernel下载及编译Rockchip SDK中GKI相关目录介绍Rockchip GKI编译代码修改编译固件烧写KO编译及修改添加新的模块驱动的方法调试ko方法开机log确认uboot阶段Android阶段KO加载KO…...
手把手教你原生JavaScript打造丝滑流畅的轮播图,让你的网站瞬间提升用户体验!
简介 轮播图是网页设计中常见的交互组件之一,用于展示多张图片或内容,让用户能够方便地浏览、切换和选择。本文将介绍如何使用原生 JavaScript 手写一个简单的轮播图,并且通过代码解释实现细节。 目录 简介 HTML 结构 CSS 样式 JavaScr…...
git常用基本操作
克隆远程代码更新本地代码 git clone <-b | -branch> [branch name] [repository URL] git pull #拉取远程仓库代码,更新本地仓库 git merge <branch-name> #合并目标分支 建立本地仓库分支 git branch #查看当…...

剑指 Offer —— 数组和字符串
文章目录剑指 Offer 04. 二维数组中的查找代码实现解题方案 思路算法步骤剑指 Offer 05. 替换空格题目描述代码实现解题方案 思路算法步骤剑指 Offer 11. 旋转数组的最小数字 - 解决方案题目描述剑指 Offer 04. 二维数组中的查找 在一个 n * m 的二维数组中: 每…...

Java 字符编码
编码:数据存储进计算机中需要转换为二进制存储,这个过程就是编码。 解码:计算机读取数据并展示在页面上,需要将二进制转换为人类语言的过程,叫做解码。 乱码:如果编码和解码时使用的码表不一样,…...

ubuntu-9-安装chrony时间同步
使用chrony搭建时间同步服务器 [Linux系列]Chrony时间同步服务器 配置chrony服务,实现服务器时间自动同步 linux上内网环境配置NTP时间同步详解 经验体会:解决Ubuntu 18.04Windows双系统时间不同步的问题 1 时间同步 我们知道一台电脑主机,…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...

python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...