• 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
    解释:链表中没有环。

    思路:
    双指针会产生两次“相遇”

    双指针的第一次相遇:
    设两指针 fast,slow 指向链表头部 head 。
    令 fast 每轮走 2 步,slow 每轮走 1步。
    执行以上两步后,可能出现两种结果:

    第一种结果: fast 指针走过链表末端,说明链表无环,此时直接返回 null。
    如果链表存在环,则双指针一定会相遇。因为每走 1 轮,fast 与 slow 的间距+1,fast 一定会追上 slow 。
    第二种结果: 当fast == slow时, 两指针在环中第一次相遇。下面分析此时 fast 与 slow 走过的步数关系:
    设链表共有 a+b 个节点,其中 链表头部到链表入口 有 a 个节点(不计链表入口节点), 链表环 有 b 个节点(这里需要注意,a和 b 是未知数,例如图解上链表 a=4, b=5);设两指针分别走了 f,s步,则有:

    fast 走的步数是 slow 步数的 2 倍,即 f=2s;( fast 每轮走 2步)
    fast 比 slow 多走了 n 个环的长度,即 f=s+nb;( 双指针都走过 a 步,然后在环内绕圈直到重合,重合时 fast 比 slow 多走 环的长度整数倍 )。
    将以上两式相减得到 f=2nb,s=nb,即 fast 和 slow 指针分别走了 2n,n 个环的周长。

    双指针第二次相遇:
    令 fast 重新指向链表头部节点。此时 f=0,s=nb。
    slow 和 fast 同时每轮向前走 1 步。
    当 fast 指针走到 f=a步时,slow 指针走到 s=a+nb 步。此时两指针重合,并同时指向链表环入口,返回 slow 指向的节点即可。

    python:

    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution:
        def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
            fast,slow=head,head
            while True:
                if not (fast and fast.next):
                    return
                fast,slow=fast.next.next,slow.next
                if fast==slow:
                    break
            fast=head
            while fast!=slow:
                fast,slow=fast.next,slow.next
            return fast
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
  • 相关阅读:
    触发迅雷下载
    POJ - 3278 Catch That Cow
    吉林大学计算机组成原理软/硬件接口真题期末题书后习题
    Java.lang ClassLoader findLibrary()方法具有什么功能呢?
    mysql驱动包引起的告警问题using SSL the verifyServerCertificate property is set to ‘false‘
    【MATLAB】 03 变量与数据访问
    智慧党建小程序源码系统+在线考试+缴费+学习 功能强大 带完整的前后端搭建教程
    [架构之路-218]: 架构师责权利的定位, 架构师是技术领导者、决策者、激励者、企业家思维、战略思维、理论指导
    C++技能系列( 9 ) - 如何实现线程池【详解】
    macvlan 用于 Docker 网络
  • 原文地址:https://blog.csdn.net/ciwei24456/article/details/136624045