当前位置:网站首页>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 秒内追赶到慢指针。
边栏推荐
猜你喜欢

Lorsque le transformateur rencontre l'équation différentielle partielle

Moher College - SQL injection vulnerability test (error reporting and blind note)

Memorizing byte order of big and small end

Redis detailed tutorial

根据文件名批量生成文件夹

Implementation of ARP module in LwIP

其他服务注册与发现

Lambda expression

全網最全的混合精度訓練原理

Oracle database basics concepts
随机推荐
CEC-I 中华学习机使用说明与问答
How to control the quality of HD slip ring in the production process
Network in network (dolls)
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
redis详细教程
Target tracking shooting? Target occlusion shooting? With 1.9 billion installed petal apps, what unique features attract users?
Safe and cost-effective payment in Thailand
全網最全的混合精度訓練原理
Oracle 數據庫基本知識概念
深度学习方法求解平均场博弈论问题
2022年地理信息系统与遥感专业就业前景与升学高校排名选择
The most complete hybrid precision training principle in the whole network
1+1<2 ?! Interpretation of hesic papers
互联网行业,常见含金量高的证书,看看你有几个?
从位图到布隆过滤器,C#实现
From bitmap to bloom filter, C # implementation
超硬核!华为智慧屏上的家庭相册竟可以自动精准分类?
Freescale 单片机概述
When transformer encounters partial differential equation solution
The [MySQL] time field is set to the current time by default