环形链表系列导学

问题描述

给定一个单链表,可能存在一个环。我们的目标是找到环的入口节点,即从这个节点开始,链表进入循环。如果没有环,则返回 null

将链表问题转化为数学问题

状态序列与循环

我们可以将链表节点视为状态,每个节点的 next 指针代表状态转移函数 f f f。从头节点开始,我们可以得到一个状态序列:

  • x 0 , x 1 = f ( x 0 ) , x 2 = f ( x 1 ) , x 3 = f ( x 2 ) , … x_0, x_1 = f(x_0), x_2 = f(x_1), x_3 = f(x_2), \ldots x0,x1=f(x0),x2=f(x1),x3=f(x2),

如果链表中存在环,那么这个序列将出现循环

寻找循环起点

我们的目标是找到状态序列中最小的 μ \mu μ,使得对于某个最小的 λ \lambda λ,满足:

  • x μ = x μ + λ x_{\mu} = x_{\mu + \lambda} xμ=xμ+λ

其中:

  • μ \mu μ循环的起始位置(环的入口)
  • λ \lambda λ循环节的长度(环的长度)

Floyd 判圈算法的数学原理

阶段一:检测循环

使用两个指针:

  • 慢指针(slow):每次移动一步
  • 快指针(fast):每次移动两步

阶段二:找到循环的起始位置

数学推导

设:

  • 非环部分长度 a a a
  • 环的长度 b b b
  • 从环入口到相遇点的距离 c c c
  • 快指针在环内绕行的圈数 k k k ( k ≥ 1 k \geq 1 k1)
距离关系
  • 慢指针走的总距离
    D slow = a + c D_{\text{slow}} = a + c Dslow=a+c

  • 快指针走的总距离
    D fast = a + c + k × b D_{\text{fast}} = a + c + k \times b Dfast=a+c+k×b

  • 由于快指针速度是慢指针的两倍:
    D fast = 2 × D slow D_{\text{fast}} = 2 \times D_{\text{slow}} Dfast=2×Dslow

推导步骤
  1. 建立等式
    a + c + k × b = 2 × ( a + c ) a + c + k \times b = 2 \times (a + c) a+c+k×b=2×(a+c)

  2. 化简
    a + c + k × b = 2 a + 2 c a + c + k \times b = 2a + 2c a+c+k×b=2a+2c
    k × b = 2 a + 2 c − a − c k \times b = 2a + 2c - a - c k×b=2a+2cac
    k × b = a + c k \times b = a + c k×b=a+c

  3. 得出关系式
    a + c = k × b a + c = k \times b a+c=k×b

寻找环的入口
  • 快指针走了 a a a 步到达环入口
  • 慢指针从相遇点再走 b − c b - c bc 步也到达环入口

因为:
b − c = b − ( k × b − a ) = − ( k − 1 ) × b + a b - c = b - (k \times b - a) = - (k - 1) \times b + a bc=b(k×ba)=(k1)×b+a

具体例子

假设:

  • 非环部分长度 a = 3 a = 3 a=3
  • 环的长度 b = 4 b = 4 b=4
  • 快指针在环内绕行的圈数 k = 1 k = 1 k=1

根据推导:
a + c = k × b ⟹ c = k × b − a = 1 × 4 − 3 = 1 a + c = k \times b \implies c = k \times b - a = 1 \times 4 - 3 = 1 a+c=k×bc=k×ba=1×43=1

  • 慢指针走的总距离
    D slow = a + c = 3 + 1 = 4 D_{\text{slow}} = a + c = 3 + 1 = 4 Dslow=a+c=3+1=4

  • 快指针走的总距离
    D fast = 2 × D slow = 8 D_{\text{fast}} = 2 \times D_{\text{slow}} = 8 Dfast=2×Dslow=8

验证快指针的距离:
D fast = a + c + k × b = 3 + 1 + 1 × 4 = 8 D_{\text{fast}} = a + c + k \times b = 3 + 1 + 1 \times 4 = 8 Dfast=a+c+k×b=3+1+1×4=8

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

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

相关文章

springboot vue 开源 会员收银系统 (12)购物车关联服务人员 订单计算提成

前言 完整版演示 http://120.26.95.195/ 开发版演示 http://120.26.95.195:8889/ 在之前的开发进程中,我们完成订单的挂单和取单功能,今天我们完成购物车关联服务人员,用户计算门店服务人员的提成。 1.商品关联服务人员 服务人员可以选择 一…

linux安全管理-账号口令

文章目录 1 设备密码复杂度策略2 设备密码生存周期、最小长度、更改最小间隔天数和过期前警告天数3 使用 PAM 认证禁止指定组之外的用户使用 su 切换到 root4 制作用户权限对照表 1 设备密码复杂度策略 1、配置内容 检查密码复杂度策略中设置的特殊字符、大写字母、小写字母和…

JiaJia-CP-1,2,3的WP(1)

一.JiaJia-CP-1 这是ctfshow里电子取证里面的题,以下下是我做题时的WP 审题,最后提交格式要进行md5 加密,给各位CTFer们找了一个md5加密的网站(加紧收藏哦): MD5 在线加密工具 | 菜鸟工具 1.拿到题目&am…

【C语言】关于 JavaScript 与 C语言在函数嵌套定义方面的差异探讨

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C语言 文章目录 💯前言💯JavaScript:允许函数嵌套定义与闭包的灵活性JavaScript 的闭包机制JavaScript 中嵌套函数的应用场景 💯C 语言:不允许函数嵌套定义的…

Proxy详解

监听对象属性: 在之前,若希望监听一个对象的相关操作,可通过Object.defineProty来进行监听,它必须深度遍历对象里的每一个属性 const obj{name:why,age:18,height:1.65 } // 需求:监听对象属性的所有操作 // 监听属性…

基于SpringBoot共享汽车管理系统【附源码】

基于SpringBoot共享汽车管理系统 效果如下: 系统注册页面 系统登陆页面 系统管理员主页面 用户信息管理页面 汽车投放管理页面 使用订单页面 汽车归还管理页面 研究背景 随着计算机技术和计算机网络的逐渐普及,互联网成为人们查找信息的重要场所。二十…

【天地图】HTML页面实现车辆轨迹、起始点标记和轨迹打点的完整功能

目录 一、功能演示 二、完整代码 三、参考文档 一、功能演示 运行以后完整的效果如下: 点击开始,小车会沿着轨迹进行移动,点击轨迹点会显示经纬度和时间: 二、完整代码 废话不多说,直接给完整代码,替换…

【Jenkins】docker 部署 Jenkins 踩坑笔记

文章目录 1. docker pull 超时2. 初始化找不到 initialAdminPassword 1. docker pull 超时 docker pull 命令拉不下来 docker pull jenkins/jenkins:lts-jdk17 Error response from daemon: Get "https://registry-1.docker.io/v2/": 编辑docker配置 sudo mkdir -…

Docker: 教程07 - ( 如何对 Docker 进行降级和升级)

如果我们使用 docker 来管理容器,那么保持 docker 引擎的更新将会是十分重要的,这一篇文章我们将会讨论如何对Docker 进行降级和升级。 准备工作 - docker 环境 我们需要拥有一个安装好 docker 的运行环境。 如果你需要了解如何安装 docker 可以通过如…

SOLID原则学习【目录篇】

文章目录 1. 前言2. ‘S’--单一职责原则(Single Responsibility Principle)3. ‘O’--开闭原则4. ‘L’--里氏替换原则5. ‘I’--接口隔离原则6. ‘D’--依赖倒置原则参考 1. 前言 SOLID原则是面向对象设计(OOD)中五个核心设计原…

继上一篇,设置弹框次数以及自适应图片弹框,部分机型(vivo)老手机不显示的问题

上一篇写的本来测试好多型号都无事, 今天下午公司的战斗机vivo横空冒出… 晕 弹框直接显示都出不来了,现在还有用这种老的机型的,但是没办法咯~ 前端遇到这种兼容性的问题就要勇于解决 主要解决了这几点: // 添加图片加载事件 <imgv-if"imageUrl":src"image…

Flink在Linux系统上的安装与入门

一、Flink的引入 这几年大数据的飞速发展&#xff0c;出现了很多热门的开源社区&#xff0c;其中著名的有Hadoop、Storm&#xff0c;以及后来的Spark&#xff0c;他们都有着各自专注的应用场景。Spark 掀开了内存计算的先河&#xff0c;也以内存为赌注&#xff0c;赢得了内存计…

scanf函数和printf函数的格式化输入输出

#include<stdio.h> int main() {int a;double b;char c;scanf("a%d,b%lf:c%c",&a,&b,&c); //float型输入时使用%f占位&#xff0c;double型使用%lf占位&#xff1b;输出时二者相同都是%f即可。if(a>0)printf("a%-10d,b%20.3lf,c%c",a…

《C++ 中 RNN 及其变体梯度问题的深度剖析与解决之道》

在当今人工智能蓬勃发展的浪潮中&#xff0c;递归神经网络&#xff08;RNN&#xff09;及其变体长短期记忆网络&#xff08;LSTM&#xff09;和门控循环单元&#xff08;GRU&#xff09;在处理序列数据方面展现出了强大的潜力。然而&#xff0c;当我们在 C中着手实现这些网络时…

【大数据学习 | Spark调优篇】Spark之JVM调优

1. Java虚拟机垃圾回收调优的背景 如果在持久化RDD的时候&#xff0c;持久化了大量的数据&#xff0c;那么Java虚拟机的垃圾回收就可能成为一个性能瓶颈。因为Java虚拟机会定期进行垃圾回收&#xff0c;此时就会追踪所有的java对象&#xff0c;并且在垃圾回收时&#xff0c;找…

ffmpeg.js视频播放(转换)

chrome 临时设置SharedArrayBuffer "C:\Program Files\Google\Chrome\Application\chrome.exe" --enable-featuresSharedArrayBuffer 引用的js及相关文件 ffmpeg.min.js ffmpeg.min.js.map ffmpeg-core.js ffmpeg-core.wasm ffmpeg-core.worker.js 以上几个现…

【随笔】AI大模型对软件开发的影响

随着 AI 技术的不断发展&#xff0c;AI大模型正在重塑软件开发流程&#xff0c;从代码自动生成到智能测试&#xff0c;未来&#xff0c;AI 大模型将会对软件开发者、企业&#xff0c;以及整个产业链都产生深远的影响。欢迎探讨 AI 是如何重塑软件开发的各个环节以及带来的新的流…

Java的常识

程序员分类 初级程序员(大学毕业一年以内)大概月薪:2-5K 初中级程序员(工作经验2-3年)大概月薪:6-10K 中级程序员(工作经验4-5年)大概月薪:10-15K 高级程序员(工作经验5++)大概月薪:15K++ 普通公司对于程序员的月薪资天花板25K 工作实景 微信小程序、手机APP、写…

常用的数据结构

队列(FIFO) 栈(LIFO) 链表 hash表 hash冲突处理 开放式寻址 线性探测 表示依次检查索引为 hash(key) + 1、hash(key) + 2 ... 的位置。i 是冲突后的探查步数。公式:hash(i) = (hash(key) + i) % TableSize二次探查 规则:冲突后探查的步长是平方递增的,例如,检查位置为 hash…

SpringSecurity6

1.快速入门 2.SpringSecurity底层原理 使用的是委托过滤器,委托过滤器实际上就是 sevlet 过滤器 将自己放入Sevlet环境下 然后里面是一个 过滤器链代理 代理类下又是一个代理过滤器链的集合, 对于不同请求可以有不同的过滤器链, springsecurity有个默认的过滤器链 Defau…