LeetCode 142:环形链表 II
题目
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。
思路
设置快慢指针,判断链表是否有环,若有环,则从链表起始位置和快慢指针相遇位置出发,必会在环入口相遇。
代码
public class Solution {
public ListNode detectCycle(ListNode head) {
if(head==null||head.next==null)
return null;
ListNode fast=head.next.next,slow=head.next;
while(fast!=null&&fast.next!=null)//需要判断fast.next也不为空
{
if(fast==slow)
break;
fast=fast.next.next;
slow=slow.next;
}
if(fast!=slow)
return null;
ListNode start=head;
while(start!=slow)
{
start=start.next;
slow=slow.next;
}
return start;
}
}
反思
①
fast是走两步,slow是走一步,其实相对于slow来说,fast是一个节点一个节点的靠近slow的,所以如果有环fast一定可以和slow重合。
②
假设从头结点到环形入口节点 的节点数为x。 环形入口节点到 fast指针与slow指针相遇节点节点数为y。 从相遇节点 再到环形入口节点节点数为 z。
那么相遇时: slow指针走过的节点数为: x + y, fast指针走过的节点数: x + y + n (y + z),n为fast指针在环内走了n圈才遇到slow指针, (y+z)为 一圈内节点的个数A。
因为fast指针是一步走两个节点,slow指针一步走一个节点, 所以 fast指针走过的节点数 = slow指针走过的节点数 * 2:
(x + y) * 2 = x + y + n (y + z)
整理公式之后为如下公式:x = (n - 1) (y + z) + z 注意这里n一定是大于等于1的,因为 fast指针至少要多走一圈才能相遇slow指针。
当 n为1的时候,公式就化解为 x = z,
n如果大于1,就是fast指针在环形转n圈之后才遇到 slow指针。
标签:II,slow,142,fast,next,链表,节点,指针
From: https://www.cnblogs.com/Janecodehouse/p/17051921.html