LC 141. 环形链表

题目描述

这是 LeetCode 上的 141. 环形链表 ,难度为 简单

给你一个链表的头节点 head,判断链表中是否有环。

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

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

示例 1:

1
2
3
4
5
输入:head = [3,2,0,-4], pos = 1

输出:true

解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

1
2
3
4
5
输入:head = [1,2], pos = 0

输出:true

解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

1
2
3
4
5
输入:head = [1], pos = -1

输出:false

解释:链表中没有环。

提示:

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

进阶:你能用 $O(1)$(即,常量)内存解决此问题吗?


快慢指针

这是一道「快慢指针」的模板题。

使用两变量 slowfast 分别代表快慢指针,slow 每次往后走一步,而 fast 每次往后两步,两者初始化均为 head

若链表无环,则 fast 必然会先走到结尾,算法正常结束;若链表有环,当 slow 来到环入口时,fast 必然已经在环中的某个位置,此时再继续进行,由于存在速度差,发生相遇必不可能是 slow 追上 fast,而只能是 fast 从后方追上 slow,由于速度差为 $1$,因此最多会消耗不超过环节点个数的回合,两者即会相遇。

代码:

1
2
3
4
5
6
7
8
9
10
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next; fast = fast.next.next;
if (slow == fast) return true;
}
return false;
}
}

  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(1)$

最后

这是我们「刷穿 LeetCode」系列文章的第 No.141 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!