剑指Offer-52——链表中环的入口节点
程序员文章站
2022-03-14 21:00:33
...
题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路解析
这个方法不是自己的,但是确实解法很巧妙因此就以此方法作为博客内容了。
原方法地址:https://blog.nowcoder.net/n/deaa284f105e48f49f38b5d7cb809cd7?f=comment
思路描述:
假设链表结构如下:
- 首先判断是否是环。设置两个指针,fasth和slwo。fast一次走两步,slow一次走一步。fast肯定会比slow更早的进入环中,且经过多次循环,最终如果和slow相遇了(假设相遇在P点),说明fast一直在转圈,存在环。
在这个过程中slow走过的距离是a+b
,fast走过的距离是:a+nb+(n-1)c
。(这里的n倍b和n-1倍c的原因是,由于最后在P点相遇了,因此fast说走的路程少1个c)
因此速度关系式如下:2(a+b) = a+nb+(n-1)c 可知,由于要满足等式关系,n = 2。而得到a = c。- 然后在进行环入口的判断。
设置slow2从pHead开始进入,而slow此时正从相遇的q点出发。由于a = c,当slow2于slow相遇的地方,就是环入口点。
代码
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ListNode EntryNodeOfLoop(ListNode pHead)
{
if(pHead == null || pHead.next ==null) return null;
ListNode fast = pHead;
ListNode slow = pHead;
while(fast!=null||fast.next!=null){
//由于如果存在环,就会一直循环下去,如果不存在环,就会在满足要求后跳出循环,返回一个null
fast = fast.next.next;//快指针一次走两步
slow = slow.next;//慢指针一次走一步
if(fast==slow){
//当快慢指针相遇
ListNode slow2 = pHead;
while(slow2!=slow){
slow2 = slow2.next;//slow2指针从phead出进入一次走一步当与slow相遇即为环入口
slow = slow.next;
}
return slow2;
}
}
return null;
}
}
推荐阅读
-
剑指offer25:复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),结果返回复制后复杂链表的head。
-
PHP实现找出链表中环的入口节点
-
leetcode 160剑指offer面试题52. 两个链表的第一个公共节点(python3)
-
《剑指offer》-- 两个链表的第一个公共结点、链表中环的入口结点、删除链表中的重复结点
-
剑指 Offer 18. 删除链表的节点
-
(三)剑指offer35 两个链表的第一个公共节点
-
牛客 剑指Offer 单链表判断是否有环 以及找出环的入口点
-
PHP实现找出链表中环的入口节点
-
剑指offer25:复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),结果返回复制后复杂链表的head。
-
剑指offer55:链表中环的入口结点