【Leetcode】142. 环形链表 II(Linked List Cycle II)

No142. 环形链表 II

题目

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。

说明:不允许修改给定的链表。

你是否可以使用 O(1) 空间解决此题?

示例1

在这里插入图片描述

  • 输入:head = [3,2,0,-4], pos = 1
  • 输出:返回索引为 1 的链表节点
  • 解释:链表中有一个环,其尾部连接到第二个节点。

示例2

在这里插入图片描述

  • 输入:head = [1,2], pos = 0
  • 输出:返回索引为 0 的链表节点
  • 解释:链表中有一个环,其尾部连接到第一个节点。

示例3

在这里插入图片描述

  • 输入:head = [1], pos = -1
  • 输出:null
  • 解释:链表中没有环。

提示

  • 链表中节点的数目范围是 [0, 104]
  • -105 <= Node.val <= 105
  • pos 为 -1 或者链表中的一个 有效索引 。

思路:

在这里插入图片描述

设p和q均从起点出发,速度分别是v和2v,考虑的是如何返回处于入口处的结点,首先考虑x,y,z三者的关系,有一个等式是:

x + y v = x + y + n ( y + z ) 2 v \frac{x+y}{v} = \frac{x+y+n(y+z)}{2v} vx+y=2vx+y+n(y+z)

化简为:

x = z + ( n − 1 ) ( y + z ) x = z + (n-1)(y+z) x=z+(n1)(y+z)

此时p和q均在汇合点,那么再令res从起点出发,速度与p保持一致,它们一定会在入口处相遇,代码如下:

解题代码(Python3)

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        if not head:
            return None
        p = q = head
        while q and q.next:
            p = p.next
            q = q.next.next
            if p == q:
                res = head
                while 1:
                    if res == p:
                        return res
                    res = res.next
                    p = p.next
        return None

复杂度分析:

  • 时间复杂度O(n) 2次O(n)
  • 空间复杂度O(1)

运行结果:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Xiao_Spring/article/details/113757058
今日推荐