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)$(即,常量)内存解决此问题吗?
快慢指针
这是一道「快慢指针」的模板题。
使用两变量 slow
和 fast
分别代表快慢指针,slow
每次往后走一步,而 fast
每次往后两步,两者初始化均为 head
。
若链表无环,则 fast
必然会先走到结尾,算法正常结束;若链表有环,当 slow
来到环入口时,fast
必然已经在环中的某个位置,此时再继续进行,由于存在速度差,发生相遇必不可能是 slow
追上 fast
,而只能是 fast
从后方追上 slow
,由于速度差为 $1$,因此最多会消耗不超过环节点个数的回合,两者即会相遇。
代码:1
2
3
4
5
6
7
8
9
10public 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 协议 ,转载请注明出处!