Java for You 数据结构 环形链表 II | LeetCode 142

环形链表 II | LeetCode 142

题目描述

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

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

​

示例 1:

image.png

示例 2:

image.png

示例 3:

image.png

​

提示:

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

​

题目解析

基于 141. 环形链表 的解法,直观地来说就是当快慢指针相遇时,让其中任一个指针指向头节点,然后让它俩以相同速度前进,再次相遇时所在的节点位置就是环开始的位置。

我们假设快慢指针相遇时,慢指针 slow 走了 k 步,那么快指针 fast 一定走了 2k 步:

  • fast 一定比 slow 多走了 k 步,这多走的 k 步其实就是 fast 指针在环里转圈圈,所以 k 的值就是环长度的「整数倍」。
  • 假设相遇点距环的起点的距离为 m,那么环的起点距头结点 head 的距离为 k – m,也就是说如果从 head 前进 k – m 步就能到达环起点。
  • 巧的是,如果从相遇点继续前进 k – m 步,也恰好到达环起点:

​

所以,只要我们把快慢指针中的任一个重新指向 head,然后两个指针同速前进,k – m 步后一定会相遇,相遇之处就是环的起点了。

参考代码

以下为 Java 代码。

​

​

复杂度分析

​

  • 时间复杂度:O(N),其中 N 为链表中节点的数目。
  • 在最初判断快慢指针是否相遇时,slow 指针走过的距离不会超过链表的总长度;
  • 随后寻找入环点时,走过的距离也不会超过链表的总长度。因此,总的执行时间为 O(N)+O(N)=O(N)。
  • 空间复杂度:O(1)。
本文由 java4u.cn 发布,可自由转载、引用,但需署名作者且注明文章出处(作者:白色蜗牛,出处:java4u.cn)。如转载至微信公众号,请在文末添加作者公众号二维码。 https://java4u.cn/algorithms/3297.html

作者: 蜗牛

相交链表 | LeetCode 160

环形链表 | LeetCode 141

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

联系我们

公众号:蜗牛互联网

在线咨询: QQ交谈

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部