链表操作III

        看这篇文章之前,可以先看看链表操作I和链表操作II。而这篇文章主要是想说明两道关于链表环的问题。

环形链表

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

在这里插入图片描述
注:图片转载自leetcode官网。

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

        这题的基本思路是使用快慢指针,快指针每次走两步,慢指针每次走一步,如果链表无环,fast最终会指向null,如果链表有环,则慢指针最终会与快指针相遇。以上图的为示例,说明上述代码的执行过程。slow走一步到2,fast走两步到0,没有相遇。fast走两步到2,slow走一步到0,没有相遇。fast走两步到-4,slow走两步到-4,二者相遇,返回true。

环形链表II

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

public class Solution {public ListNode detectCycle(ListNode head) {ListNode slow = head;ListNode fast = head;if(head == null) return null;while(fast.next != null && fast.next.next != null){slow = slow.next;fast = fast.next.next;if(fast == slow){slow = head;while(slow != fast){slow = slow.next;fast = fast.next;}return slow;}}return null;}
}

        与上一题相比,这题还需要找到入环的位置。这题的基本思路也是使用快慢指针,快指针每次走两步,慢指针每次走一步,当两个指针相遇时,重新让慢指针从链表头开始走,快指针从相遇点开始走,当两个指针再次相遇的位置即为入环位置。leetcode上给出了详细的解释,这里按个人理解说明一下。
在这里插入图片描述
注:图片转载自leetcode官网。
        设链表表头到入环点共有a个结点,指针进入环后按图中顺时针箭头行走,慢指针进入环后走过b个结点后相遇。此时快指针走过的路径为a + n(b + c) + b。b + c为整个环,n表示快指针走过整个环的圈数。同时还需要满足一个要求就是快指针走过的路径是满指针路径的两倍,因为快指针每次走两步,慢指针每次走一步。慢指针走过的路径(结点数)为a + b。快指针走过的路径就为2 * (a + b),那就是说a + n(b + c) + b = 2 * (a + b)。整理一下得到a = c + (n - 1)(b + c)。也就是说链表头到入环点的路径长等于(n - 1)圈的整个环长度加上相遇点到入环点的距离。换句话说,如果一个指针从链表头出发,一个指针从相遇点出发,那么从链表头开始走的指针走到入环点时,一定会与从入环点开始走的指针相遇,而此时从相遇点开始走的指针走过的路径长度为(n - 1)圈的环长加上相遇点到入环点的距离。这就是为什么快慢指针相遇后,将慢指针(不一定要慢指针,快指针或者重新定义一个指针都可以)从链表头开始走,而快指针从相遇点开始走,当二者再次相遇时,再次相遇点就是入环点。

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

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

相关文章

ffmpeg支持MP3编码的方法

目录 现象 解决办法 如果有编译包没有链接上的情况 现象 解决办法 在ffmpeg安装包目录下 ,通过./configure --list-encoders 和 ./configure --list-decoders 命令可以看到,ffmpeg只支持mp3解码,但是不支持mp3编码。 上网查寻后发现&…

【C++初阶】List使用特性及其模拟实现

1. list的介绍及使用 1.1 list的介绍 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。 2. list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前…

【PHP开发工程师详细讲解分析】——网站注册账号(头像的上传操作),让自己喜欢的头像更换畅通无阻

👨‍💻个人主页:开发者-曼亿点 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 曼亿点 原创 👨‍💻 收录于专栏&#xff1a…

设计模式-00 设计模式简介之几大原则

设计模式-00 设计模式简介之几大原则 本专栏主要分析自己学习设计模式相关的浅解,并运用modern cpp 来是实现,描述相关设计模式。 通过编写代码,深入理解设计模式精髓,并且很好的帮助自己掌握设计模式,顺便巩固自己的c…

鸿蒙OpenHarmony【小型系统运行案例】 (基于Hi3516开发板)

运行 启动系统 在完成Hi3516DV300的烧录后,还需要设置BootLoader引导程序,才能运行OpenHarmony系统。 在Hi3516DV300任务中,单击Configure bootloader(Boot OS)进行配置即可。 说明: DevEco Device Tool…

02 IO口的操作

文章目录 前言一、IO的概念1.IO接口2.IO端口 二、CPU和外设进行数据传输的方法1.程序控制方式1.1 无条件1.2 查询方式 2.中断方式3.DMA方式 一、方法介绍和代码编写1.前置知识2.程序方式1.1 无条件方式1.1.1 打开对应的GPIO口1.1.2 初始化对应的GPIO引脚1.1.2.1 推挽输出1.1.2.…

Docker常用命令(镜像、容器、网络)

一、镜像 1.1 存出镜像 将镜像保存成为本地文件 格式&#xff1a;docker save -o 存储文件名 存储的镜像docker save -o nginx nginx:latest 1.2 载入镜像 将镜像文件导入到镜像库中 格式&#xff1a;docker load < 存出的文件或docker load -i 存出的文件…

【大语言模型LLM】- Meta开源推出的新一代大语言模型 Llama 3

&#x1f525;博客主页&#xff1a;西瓜WiFi &#x1f3a5;系列专栏&#xff1a;《大语言模型》 很多非常有趣的模型&#xff0c;值得收藏&#xff0c;满足大家的收集癖&#xff01; 如果觉得有用&#xff0c;请三连&#x1f44d;⭐❤️&#xff0c;谢谢&#xff01; 长期不…

c++的策略模式,就是多态

一、定义&#xff1a; 策略模式定义了一系列的算法&#xff0c;并将每一个算法封装起来&#xff0c;而且使它们还可以相互替换。 策略模式让算法独立于使用它的客户而独立变化。 二&#xff0c;核心 抽象策略&#xff08;抽象基类&#xff09;&#xff08;Strategy&#xff09…

【01-机器学习入门:理解Scikit-learn与Python的关系】

文章目录 前言Python与机器学习Scikit-learn简介Scikit-learn与Python的关系使用Scikit-learn进行机器学习结语前言 在当今的数据科学和人工智能领域,机器学习已经成为了一个不可或缺的组成部分。而对于那些刚刚踏入这一领域的新手来说,理解机器学习的基本概念和找到合适的工…

消灭AI“耗电巨兽”?暴雨服务器推出液冷节能降耗算力方案

在科技飞速发展的今天&#xff0c;人工智能已成为驱动未来的重要力量。随着AI及大模型技术的进一步普及和应用场景的拓宽&#xff0c;相关算力需求呈指数级增长&#xff0c;大规模的AI训练和推理过程均需消耗大量电力&#xff0c;如同一个巨大的电力黑洞&#xff0c;吞噬着海量…

安全小课堂丨什么是暴力破解?如何防止暴力破解

什么是暴力破解&#xff1f; 暴力破解也可称为穷举法、枚举法&#xff0c;是一种比较流行的密码破译方法&#xff0c;也就是将密码进行一一推算直到找出正确的密码为止。比如一个6位并且全部由数字组成的密码&#xff0c;可能有100万种组合&#xff0c;也就是说最多需要尝试10…