【忍者算法】从公路跑步到链表成环:探索环形链表检测|LeetCode第141题 环形链表
从公路跑步到链表成环:探索环形链表检测
生活中的环形
想象两个人在环形跑道上跑步,一个跑得快,一个跑得慢。如果他们一直跑下去,快的跑者一定会从后面追上慢的跑者。这就是我们今天要讨论的环形链表问题的现实映射。在跑道上,两个速度不同的跑者相遇就说明跑道是环形的;同样在链表中,如果两个速度不同的指针相遇,就说明链表中存在环。
问题描述
LeetCode第141题"环形链表"要求:给你一个链表的头节点 head,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。
例如:
输入:3 → 2 → 0 → -4
↑___________|
输出:true
解释:链表中存在一个环,尾节点连接到第二个节点
输入:1 → 2
↑___|
输出:true
解释:链表中存在一个环,尾节点连接到第一个节点
输入:1 → 2 → 3 → 4
输出:false
解释:链表中不存在环
简单解法:哈希表记录
最直观的想法是用一个哈希表记录每个走过的节点。就像在跑道上撒面包屑,如果遇到已经撒过面包屑的地方,说明路径形成了环。
哈希表解法实现
public boolean hasCycle(ListNode head) {
Set<ListNode> seen = new HashSet<>();
while (head != null) {
// 如果已经见过这个节点,说明有环
if (seen.contains(head)) {
return true;
}
// 记录当前节点
seen.add(head);
head = head.next;
}
return false;
}
优化解法:快慢指针(Floyd判圈算法)
这个经典算法也被称为"龟兔赛跑算法",就像我们开始说的跑步场景:让一快一慢两个指针在链表上移动,如果存在环,快指针最终一定会追上慢指针。
为什么快慢指针一定会相遇?
想象在环形跑道上:
- 快指针每次走2步,慢指针每次走1步
- 相对来说,快指针每次都在追赶慢指针1步
- 如果有环,这就像在操场上追赶,快指针一定会追上慢指针
- 如果无环,快指针会先到达终点
代码实现与详解
public boolean hasCycle(ListNode head) {
if (head == null || head.next == null) {
return false;
}
// 初始化快慢指针
ListNode slow = head;
ListNode fast = head;
// 快指针每次走两步,慢指针每次走一步
while (fast != null && fast.next != null) {
slow = slow.next; // 慢指针走一步
fast = fast.next.next; // 快指针走两步
// 如果两个指针相遇,说明有环
if (slow == fast) {
return true;
}
}
// 如果快指针到达链表末尾,说明无环
return false;
}
图解过程
以一个有环链表为例:
1) 初始状态:
3 → 2 → 0 → 4
↑_________|
S,F
(S=slow, F=fast)
2) 第一次移动后:
3 → 2 → 0 → 4
↑_________|
S F
3) 第二次移动后:
3 → 2 → 0 → 4
↑_________|
S F
4) 最终相遇:
3 → 2 → 0 → 4
↑_________|
S,F
复杂度比较
哈希表解法:
- 时间复杂度:O(n)
- 空间复杂度:O(n),需要存储已访问节点
- 优点:思路直观,容易实现
- 缺点:需要额外空间
快慢指针解法:
- 时间复杂度:O(n)
- 空间复杂度:O(1),只需要两个指针
- 优点:空间效率高,实现优雅
- 缺点:需要理解快慢指针的数学原理
核心原理解析
1. 数学证明
为什么快慢指针一定会相遇?
- 假设环长为K,入环前长度为N
- 慢指针走S步时,快指针走2S步
- 快指针多走的S步一定是环长K的整数倍
- 因此快慢指针一定会在入环后的K-N步内相遇
2. 临界情况分析
- 空链表
- 单节点链表
- 环的长度为1(自环)
- 入环点在开头或结尾
实用技巧总结
解决环形问题的关键点:
- 掌握快慢指针技巧
- 理解环形结构的特性
- 考虑边界情况
- 注意指针移动的顺序
相关的环形问题:
- 找到环的入口点
- 计算环的长度
- 找到环中的特定节点
小结
环形链表的检测问题是链表操作中的一个经典问题。它教会我们:
- 如何用最小的空间解决复杂问题
- 快慢指针这个强大的算法技巧
- 如何将现实问题映射到算法思维
- 优雅解法往往来自于深刻的数学原理
建议:多思考快慢指针的应用场景,它不仅用于检测环,还可以:
- 找到链表中点
- 判断链表是否为回文
- 找到倒数第K个节点
这些问题都可以用类似的思维方式来解决!
作者:忍者算法
公众号:忍者算法
我准备了一份刷题清单,以及这些题目的详细题解,覆盖了绝大部分常见面试题。我可以很负责任地说,只要你把这些题真正掌握了,80%的算法面试都能遇到相似题目。公众号回复【刷题清单】获取~
【忍者算法】从公路跑步到链表成环:探索环形链表检测|LeetCode第141题 环形链表的更多相关文章
- 【python】Leetcode每日一题-旋转链表
[python]Leetcode每日一题-旋转链表 [题目描述] 给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置. 示例1: 输入:head = [1,2,3,4,5] ...
- 【python】Leetcode每日一题-反转链表 II
[python]Leetcode每日一题-反转链表 II [题目描述] 给你单链表的头节点 head 和两个整数 left 和 right ,其中 left <= right .请你反转从位置 ...
- Leetcode 141题 环形链表(Linked List Cycle) Java语言求解
题目描述: 给定一个链表,判断链表中是否有环. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 -1,则在该链表中没有环. Map ...
- [Leetcode] 第148题 排序链表
一.题目描述 在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序. 示例 1: 输入: 4->2->1->3 输出: 1->2->3->4 示 ...
- 【LeetCode题解】142_环形链表2(Linked-List-Cycle-II)
目录 描述 解法一:哈希表 思路 Java 实现 Python 实现 复杂度分析 解法二:双指针 思路 Java 实现 Python 实现 复杂度分析 描述 给定一个链表,返回链表开始入环的第一个节点 ...
- LeetCode 上最难的链表算法题,没有之一!
题目来源于 LeetCode 第 23 号问题:合并 K 个排序链表. 该题在 LeetCode 官网上有关于链表的问题中标注为最难的一道题目:难度为 Hard ,通过率在链表 Hard 级别目前最低 ...
- 《数据结构与算法之美》 <05>链表(下):如何轻松写出正确的链表代码?
想要写好链表代码并不是容易的事儿,尤其是那些复杂的链表操作,比如链表反转.有序链表合并等,写的时候非常容易出错.从我上百场面试的经验来看,能把“链表反转”这几行代码写对的人不足 10%. 为什么链表代 ...
- 【算法训练营day4】LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表II
[算法训练营day4]LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表 ...
- c++ LeetCode (网易面试题和链表以及树篇) 五道算法例题代码详解(三)
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/11209807.html 一.1道网易c++的面试题 我当时第一时间的解答方案 #include ...
- 【LeetCode题解】141_环形链表
目录 141_环形链表 描述 解法一:哈希表 思路 Java 实现 Python 实现 解法二:双指针(龟兔算法) 思路 Java 实现 Python 实现 141_环形链表 描述 给定一个链表,判断 ...
随机推荐
- Limit线段树题单题解(更新中)
P3373 线段树模板 2 \(1 \leq n \leq 10^5\) 题解:考查标记与标记的合并 我们考虑打两个懒惰标记实现区间乘和区间加 线段树维护区间和 对于信息与信息的合并:左儿子加上右儿子 ...
- cv2, pil.image, plt.image 读图的差异
人是习惯性动物,当我们第一次用opencv时,肯定会觉得opencv的imread()方式很奇怪,做图像出来天天说图像是RGB图RGB图,可opencv读出来的图,却是BGR的顺序.是不是很奇怪,还不 ...
- GienTech动态|入选软件和信息技术服务名牌企业;荣获城市数字化转型优秀案例;参加第四届深圳国际人工智能展
中电金信入选"2023第二届软件和信息技术服务名牌企业" 近日,中国电子信息行业联合会发布了"2023第二届软件和信息技术服务名牌企业"名单,中电金信入 ...
- 所有 HTML attribute - prop 对照表
attr global tags prop aria-activedescendant true all aria-atomic true all aria-autocomplete true ...
- Tomcat 已集成 CROS Fitler ExpiresFilter 等一堆常用 Filter
http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html 再也不需要三方包提供的 filter 了
- Qt编写linux系统onvif工具(支持预览/云台/预置位/录像等)
一.功能特点 广播搜索设备,支持IPC和NVR,依次返回. 可选择不同的网卡IP进行对应网段设备的搜索. 依次获取Onvif地址.Media地址.Profile文件.Rtsp地址. 可对指定的Prof ...
- Qt音视频开发40-ffmpeg采集桌面并录制
一.前言 之前用ffmpeg打通了各种视频文件和视频流以及本地摄像头设备的采集,近期有个客户需求要求将整个桌面屏幕采集下来,并可以录制保存成MP4文件,以前也遇到过类似的需求,由于没有搞过,也没有精力 ...
- Qt编写地图综合应用23-标注点交互
一.前言 地图项目应用中,标注点的交互使用频率非常高,这应该是最常用的场景,比如从数据库中读取出来设备的信息包括经纬度坐标,然后需要在地图上显示对应的设备,这就需要用addMarker函数来动态添加标 ...
- Net6之Jwt认证+Bearer认证 2.0
以前接触过,写过博客,第二次再写有了新的体会.第一次博客:https://www.cnblogs.com/zhang-3/p/16184067.html 过程: 生成token令牌(钥匙) 添加bea ...
- 抖音技术分享:飞鸽IM桌面端基于Rust语言进行重构的技术选型和实践总结
本文由ELab团队公众号授权发布,原题<Rust语言在IM客户端的实践>,来自抖音电商前端团队的分享,本文有修订和改动. 1.引言 本文将介绍飞鸽IM前端团队如何结合Rust对飞鸽客户端接 ...