当前位置:网站首页>LeetCode 142. 环形链表 II
LeetCode 142. 环形链表 II
2022-06-27 00:11:00 【碳烤小肥羊。。。】
题目描述:给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。不允许修改 链表。
方法一:使用map集合
一个非常直观的思路是:声明一个map集合(key:结点, value:记录结点位置),然后遍历链表中的每个节点,判断该结点是否在于map集合中,如果不存在将该结点加入到map集合中,如果存在,说明该链表存在环,返回该结点即可。
/** * 使用map集合 * @param head * @return */
public static ListNode detectCycle(ListNode head){
if(head == null || head.next == null){
return null;
}
Map<ListNode, Integer> map = new HashMap<>();
int pos = 0; // 初始索引为0
while (head != null){
if(map.containsKey(head)){
return head;
}
map.put(head, pos++);
head = head.next;
}
// head == null跳出while循环,说明链表不含链
return null;
}
方法二:快慢指针
我们使用两个指针,fast 与 slow。它们起始都位于链表的头部。随后,slow 指针每次向后移动一个位置,而 fast指针向后移动两个位置。如果链表中存在环,则 fast指针最终将再次与slow 指针在环中相遇。
如下图所示,设链表中环外部分的长度为 x。slow 指针进入环后,又走了 y 的距离与 fast 相遇。此时,fast指针已经走完了环的 n 圈,因此它走过的总距离为 x + n ( y + z ) + y = x + ( n + 1 ) y + z 。 x + n(y + z) + y = x + (n+1)y + z。 x+n(y+z)+y=x+(n+1)y+z。
根据题意,任意时刻,fast 指针走过的距离都为 slow 指针的 2 倍。因此,我们有 x + ( n + 1 ) y + z = 2 ( x + y ) * x = z + ( n − 1 ) ( y + z ) x + (n+1)y + z = 2(x + y) * x=z+(n−1)(y+z) x+(n+1)y+z=2(x+y) * x=z+(n−1)(y+z)
有了这个等量关系,我们会发现:从相遇点到入环点的距离加上 n−1 圈的环长,恰好等于从链表头部到入环点的距离。
因此,当发现 slow 与 fast相遇时,我们再额外使用两个指针index1, index2。起始,它们分别指向链表头部和slow与fast指针相遇点;随后,index1和index2 每次向后移动一个位置。最终,它们会在入环点相遇。
/** * 快慢指针思想 * @param head * @return */
public static ListNode detectCycle(ListNode head){
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null){
slow = slow.next; // slow每次走一步
fast = fast.next.next; // fast每次走两步
if(fast == slow){
// 有环
ListNode index1 = fast;
ListNode index2 = head;
// 两个指针, 从头节点和相遇节点,各走一步,直到相遇,相遇点即为环的入口
while (index1 != index2){
index1 = index1.next;
index2 = index2.next;
}
return index1;
}
}
return null;
}
思考问题1:在存在环的情况下,为何慢指针一定会和快指针相遇?
- 可以认为快指针和慢指针是相对运动的,假设慢指针的速度是 1节点/秒,快指针的速度是 2节点/秒,当以慢指针为参考系的话(即慢指针静止),快指针的移动速度就是 1节点/秒,所以肯定会相遇。
思考问题2:为什么在第一圈就会相遇呢?
- 设环的长度为 L,当慢指针刚进入环时,慢指针需要走 L 步(即 L 秒)才能走完一圈,此时快指针距离慢指针的最大距离为 L-1,我们再次以慢指针为参考系,如上所说,快指针在按照1节点/秒的速度在追赶慢指针,所以肯定能在 L 秒内追赶到慢指针。
边栏推荐
- Skills needing attention in selection and purchase of slip ring
- CPU的异常处理
- 新型冠状病毒变异Delta毒株的模拟(MindSPONGE应用)
- Super hard core! Can the family photo album on Huawei's smart screen be classified automatically and accurately?
- 接口测试框架实战(一) | Requests 与接口请求构造
- Lambda expression
- Oracle 数据库基本知识概念
- com.fasterxml.jackson.databind.exc.MismatchedInputException: Expected array or string. at [Source:x
- com.fasterxml.jackson.databind.exc.MismatchedInputException: Expected array or string. at [Source:x
- MATLAB data type - character type
猜你喜欢
随机推荐
kubeadm创建kubernetes集群
Sword finger offer 10- ii Frog jumping on steps
From bitmap to bloom filter, C # implementation
墨者学院-SQL注入漏洞测试(报错盲注)
Deep learning method for solving mean field game theory problems
记录一次换行符引起的bug
Super hard core! Can the family photo album on Huawei's smart screen be classified automatically and accurately?
CPU的异常处理
温故知新--常温常新
[UVM actual battle== > episode_3] ~ assertion, sequence, property
Can I open an account for stock trading on my mobile phone? Is it safe to open an account for stock trading on the Internet
[vscode] setting sync, a plug-in for synchronizing extensions and settings
find_circ详细使用指南
【leetcode】275. H index II
Leetcode skimming 4 Find the median of two positive arrays
kubernetes可视化界面dashboard
论文解读(LG2AR)《Learning Graph Augmentations to Learn Graph Representations》
com.fasterxml.jackson.databind.exc.MismatchedInputException: Expected array or string. at [Source:x
简单快速的数网络(网络中的网络套娃)
基于SSMP的宠物医院管理系统








