环形链表问题

news2025/1/16 5:57:49

文章目录

  • 环形链表问题
    • 1.环形链表
      • 题干
      • 思路
      • 延申问题
      • 总结
    • 2. 环形链表 II
      • 题干
      • 思路


环形链表问题

环形链表就是一个链表没有结束的位置,链表的最后一个节点它会指向链表中的某一个节点形成一个环。

拿力扣的两到题目来看

1.环形链表

题干

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false

测试用例1

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

测试用例2

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

思路

快慢指针,如果链表是有环的那么它必然不会结束。定义一个快指针fast和一个慢指针slowfast一次走2步,slow一次走1步,如果没有环fast就会走到NULL,如果有环fast就会追上slow

在这里插入图片描述

代码

bool hasCycle(struct ListNode *head) {
    if (head == NULL || head->next == NULL)
    {
        return false;
    }
    struct ListNode* fast = head;
    struct ListNode* slow = head;
    while (fast != NULL && slow != NULL && slow->next != NULL)
    {
        fast = fast->next;
        slow = slow->next->next;
        if (fast == slow)
        {
            return true;
        }
        
    }

    return false;
}

延申问题

  1. 为什么slow走一部,fast走两步,它们一定会再环里相遇,会不会永远追不上?

    不会出现追不上的情况,如果链表又换是一定能追上的。假设slow进环的时候,fast和slow的距离是 N N N,紧接着追击的过程中,fast往前走两步,slow走一步,它们每走一次,它们之间的距离都是缩小1的。

    N N N

    N − 1 N-1 N1

    N − 2 N-2 N2

    . . . ... ...

    2 2 2

    1 1 1

    0 0 0,距离缩小到0的时候就会相遇。

在这里插入图片描述

  1. slow走1步,fast走3步?走4步?走n步行不行?

    假设slow进环的时候,fast和slow的距离是 N N N,接着进行追击的时候,fast向前走3步,slow向前走1步,它们每走一次,它们之间的距离缩小2。那么就会分为两种情况。

    假设红色部分是slow入环,fast和slow的距离

在这里插入图片描述

1.如果 N N N为偶数

假设红色部分距离为10,也就是说距离 N = 10 N = 10 N=10,再追击过程中,fast走3步slow走1步,它们的距离是每次缩小2的。

10 10 10

10 − 2 10-2 102

10 − 4 10-4 104

. . . ... ...

2 2 2

0 0 0

如果 N N N为偶数,fast走3步slow走一步是可以相遇的

2.如果N为奇数

假设红色部分距离为11,也就是说距离 N = 11 N = 11 N=11,再追击过程中,fast走3步slow走1步,它们的距离是每次缩小2的。

11 11 11

11 − 2 11-2 112

11 − 4 11-4 114

. . . ... ...

11 − 10 11-10 1110

− 1 -1 1 ,当距离为 − 1 -1 1的时候fast和slow的差距就变成了 C − 1 C-1 C1, C C C为环的长度。那么这个时候 C − 1 C-1 C1恰好也是奇数,那么fast就永远也追不上slow了

总结

fast走多步,slow走一步时不可行的。

如果slow进环时,上图红色部分的距离也就是fast要追slow的距离 N N N为奇数,且环的长度为偶数,那么fast和slow就会一直在环里面打转,永远追不上。

如果距离 N N N为奇数,环的长度为奇数,fast走多部则会出现跳过slow的情况,也可能会相遇的。

2. 环形链表 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 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。

思路

这一道题相较于上一道题的区别就是,一个判断是否有环一个时找到环的入口点。这就是上一个题目的一个变形。

  • 设起点道入口点的距离为 X X X
  • 设相遇点道入口点的距离为 Y Y Y
  • 设环的大小为 C C C

在这里插入图片描述

那么慢指针slow走的路程就是 X + Y X+Y X+Y

快指针走的路程比较特殊,如果起点道入口的距离 X X X比较长,而环的大小 C C C又比较小,那么fast可能会在环里走好几圈,假设走了 N N N圈,所以快指针fast走的路程为 X + Y + N ∗ C X+Y+N*C X+Y+NC

因为快指针fast走的路程是慢指针slow的2倍,所以最后的公式就是

2 ∗ ( X + Y ) = X + N ∗ C + Y 2*(X+Y) = X+N*C+Y 2(X+Y)=X+NC+Y

化简之后就得出这么一个公式

X = N ∗ C − Y X = N*C-Y X=NCY

假设环比较大,fast刚走完一圈就和slow相遇那么 N = 1 N = 1 N=1,起点到入口点的距离就等于环的大小减去入口点到相遇点的距离。 X = C − Y X = C-Y X=CY

那么当两个指针相遇时就可以将其中一个指向起点位置,让它们同时走一步,就会在入口点相遇。

代码实现

struct ListNode *detectCycle(struct ListNode *head) 
{
    if (head == NULL || head->next == NULL)
    {
        return NULL;
    }
    struct ListNode* fast = head;
    struct ListNode* slow = head;
    while (fast != NULL && fast->next != NULL)
    {
        fast = fast->next->next;
        slow = slow->next;
        if (fast == slow)
        {
            fast = head;
            while (fast != slow)
            {
                fast = fast->next;
                slow = slow->next;
            }

            return fast;
        }
    }
    
    return NULL;
}

题目来源力扣环形链表


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

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

相关文章

JavaScript JSON解析

最近在uniapp中遇到了一个bug,排查后是json解析的问题。对uniapp开发比较熟悉的,应该会知道uni.navigateTo 这个API方法。这是官方提供用于跳转页面的方法。 有时候我们在跳转页面时会想传递一些参数,通常采用这样的方式 navigateTo(url, r…

oauth2.0--基础--6.1--SSO的实现原理

oauth2.0–基础–6.1–SSO的实现原理 1、什么是SSO 1.1、概念 在一个 多系统共存 的环境下,用户在一处登录后,就不用在其他系统中登录,就可以访问其他系统的资源。用户环境 浏览器:只能同一个浏览器,不会出现A浏览器…

zabbix部署【各模块超详细】

目录 安装zabbix 部署zabbix 配置zabbix 1. 修改语言 2. 监控linux端 3. 修改中文乱码 报警功能 报警音报警 邮件报警 脚本报警 邮件通知内容 图形模块 创建图形 创建聚合图形 percona mysql模板 nginx模板 克隆主机 网络发现 自动注册 主被动模式 🍁如果对你有帮助…

Handsontable复制列标题内容的功能

Handsontable复制列标题内容的功能 添加了通过使用3个新的上下文菜单选项复制列标题内容的功能:“使用标题复制”、“使用组标题复制”和“仅复制标题”。 添加了4个用于以编程方式复制列标题的新API方法:“copyCellsOnly()”、“copyWithColumnHeaders(…

vscode jupyter配置远程服务器开发

背景说明:本地vscode中使用jupyter编写本地python代码很方便,各种快捷键用的飞起。但是要做线上大数据分析时。在集群环境中搭建一个jupyter。使用网页端编写程序非常不习惯,所以想到能不能将线上的jupyter接口开出来,使用vscode远…

js-有关时间

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date 有关Date 返回格式 Sun Oct 10 2021 00:00:00 GMT0800 (中国标准时间) new Date() 无参数 获取当前时间new Date(value) 传入时间戳 传入一个时间戳 一个 Unix 时间戳(U…

JVM运行流程/运行时数据区

JVM运行流程 程序在执行之前先要把 java代码 转换成 字节码文件 (.class文件), JVM 首先需要把字节码通过一定的方式 类加载器 (ClassLoader) 把文件加载到内存中 运行时数据区 (Runtime Data Area) , 而字节码文件是 JVM 的一套指令集规范, 并不能直接交给底层操作系统去执行…

【大数据技术Hadoop+Spark】Hive数据仓库架构、优缺点、数据模型介绍(图文解释 超详细)

一、Hive简介 Hive起源于Facebook,Facebook公司有着大量的日志数据,而Hadoop是实现了MapReduce模式开源的分布式并行计算的框架,可轻松处理大规模数据。然而MapReduce程序对熟悉Java语言的工程师来说容易开发,但对于其他语言使用…

Anaconda为虚拟环境安装第三方库与Spyder等软件的方法

本文介绍在Anaconda中,为Python的虚拟环境安装第三方库与Spyder等配套软件的方法。 在文章Anaconda中Python虚拟环境的创建、使用与删除(https://blog.csdn.net/zhebushibiaoshifu/article/details/128334614)中,我们介绍了在Anac…

提前做好网络安全分析,运维真轻松(二)

背景 某汽车总部已部署NetInside流量分析系统,使用流量分析系统提供实时和历史原始流量。汽车配件电子图册系统是某汽车集团的重要业务系统。本次分析重点针对汽车配件电子图册系统进行预见性分析,以供安全取证、性能分析、网络质量监测以及深层网络分析…

FRP搭建内网穿透

前言 内网穿透方式很多,可以用公网IP进行端口映射,DDNS等。现在我有个云服务器,使用它做中转作为内网穿透的工具。 可以在这个网址了解下原理基础:内网穿透工具的原理与开发实战 FRP内网穿透 FRP是一个内网穿透的反向代理应用…

电压放大器工作原理及特点是什么

很多人虽然经常使用电压放大器,但是对于电压放大器的工作原理以及特点是什么都不清楚,下面就来为大家讲解。 什么是电压放大器? 电压放大器是一种能够增加信号电压的装置。对于弱信号,通常采用多级放大级联方式分直接耦合、阻容耦…

关于机器人状态估计(10)-VSLAM与VIO的3D建图,重定位与世界观综述

近期我国迎来了cov海啸,其实我也不知道我羊了没有,但并没有什么不舒服同时因为我没有测,那自然是没有羊,或者是薛定谔的羊。 近年另外一块工作的综述,这篇科普的同时,也会包含部分有价值的信息。 一. 摘要…

【面试题】 面试官:你如何实现大文件上传

大厂面试题分享 面试题库 前端面试题库 (面试必备) 推荐:★★★★★ 地址:前端面试题库 一、问题分析 如果将大文件一次性上传,会发生什么?想必都遇到过在一个大文件上传、转发等操作时,由…

如果公司线上系统突然宕机了,怎么才能确保MQ消息不丢失?

V-xin:ruyuanhadeng获得600页原创精品文章汇总PDF 一、写在前面 之前写过一篇文章《项目里接入了MQ消息中间件以后,我摸鱼的时间更长了~》,我们用一个简单易懂的电商场景给大家引入说明了一个消息中间件的使用场景。 同时,我们还…

考研英语|传统文化英语高频词汇

目录​​​​​​​ 一. 节日名称 二. 相关节日活动 三. 传统饮食 四. 传统建筑 五. 文学艺术 六. 四大发明 七. 新四大发明 一. 节日名称 1. 春节:Chinese New Years Day / Chinese Lunar New Year / the Spring Festival 2. 除夕:New Years E…

Vue2.0开发之——Vue组件-样式冲突(35)

一 概述 scoped的使用及底层原理使用deep修改子组件中的样式 二 scoped的使用及底层原理 2.1 组件之间的样式冲突问题(修改Left.vue中的h3属性,Right也被修改) 默认情况下,写在 .vue 组件中的样式会全局生效,因此很容易造成多个组件之间的样…

kubelet源码分析 syncLoopIteration(二) plegCh、syncCh

kubelet源码分析 syncLoopIteration(二) plegCh 上一篇:kubelet源码分析 syncLoopIteration(一) configCh 上一篇说了configCh管道的作用,这一篇说一下plegCh管道。这个管道主要是监听容器运行时状态的&…

搭建Python环境

搭建Python环境 文章目录搭建Python环境需要安装的环境:安装Python1)找到官网2)找到下载页面3)双击安装包4)运行 hello world安装 PyCharm1)找到官方网站2)找到下载页面3)双击安装包…

BEVFormer-accelerate:基于 EasyCV 加速 BEVFormer

导言 BEVFormer是一种纯视觉的自动驾驶感知算法,通过融合环视相机图像的空间和时序特征显式的生成具有强表征能力的BEV特征,并应用于下游3D检测、分割等任务,取得了SOTA的结果。我们在EasyCV开源框架(https://github.com/alibaba…