首页 > 其他分享 >LeetCode 142_环形链表 II

LeetCode 142_环形链表 II

时间:2023-01-14 15:45:55浏览次数:36  
标签:II slow 142 fast next 链表 节点 指针

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

相关文章