LeetCode hot 100 — 141. 环形链表2

题目信息

给定一个链表的头节点 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
解释:链表中没有环。

提示:

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

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

思路 / 启发过程

感想是看了答案我基本上不可能会做的....

我的理解上来说,答案的核心,首先要理解快慢指针的做法,然后就是用数学来解答。数学解答的核心偏向于距离表达和速度表达吧,去建立等量关系(相遇本质上就是一种路程相等的等量关系)。从表达式揭露的关系下手,然后去看怎么建立算法和解答方法

参考答案思维过程

关键是:相遇点到环入口的距离,和头节点到环入口的距离存在数学关系。

设:

复制代码
a:头节点到环入口的距离
b:环入口到相遇点的距离
c:环的长度

相遇时:

复制代码
slow 走了:a + b
fast 走了:a + b + k*c

这里注意一个细节,slow一定是在进入的第一圈就被fast追上了。原因:slow进入环后,和fast的距离肯定是 <= m的,而fast每次都会缩小和slow之间的,一个单位的距离,所以必定在slow走完第一个完整的环前,二者就相遇了。

因为 fast 速度是 slow 的两倍:

复制代码
2(a + b) = a + b + k*c

整理得到:

复制代码
a + b = k*c

所以:

复制代码
a = k*c - b

也即:

复制代码
a = (k - 1)c + (c - b)

这意味着:

复制代码
从相遇点继续走 c - b 步,会到达环入口
从头节点走 a 步,也会到达环入口

而多走完整的 (k - 1)c 圈不会改变环上的位置。

因此相遇后:

  1. 保留一个指针在相遇点。
  2. 把另一个指针重新放回头节点。
  3. 两个指针都每次走一步。
  4. 它们下一次相遇的位置就是环入口。

通过示例代码

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]:
        # 承接环形链表1的部分,先找到相遇点
        fast = head
        slow = head
        while fast is not None and fast.next is not None:
            slow = slow.next
            fast = fast.next.next
            if slow is fast:    # has circle
                # 开始找相遇节点
                fast = head # 一个节点回到头部位置
                while slow != fast:
                    fast = fast.next
                    slow = slow.next
                return fast
        return None

知道逻辑了以后写代码还是很好写的...主要是逻辑和思维过程

相关推荐
倒头就睡的小比特1 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼1 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光1 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark1 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her12 天前
并查集-听课笔记
笔记·算法·并查集
码流子2 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven2 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark2 天前
从算法设计模式看编程思维的抽象能力4
算法
2601_962218612 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法