欢迎访问LeetCode题解合集
题目描述
给定一个链表,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos
是 -1
,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true
。 否则,返回 false
。
进阶:
你能用 O(1)(即,常量)内存解决此问题吗?
示例 1:
[HTML_REMOVED]
[HTML_REMOVED]
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
[HTML_REMOVED]
[HTML_REMOVED]
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
[HTML_REMOVED]
[HTML_REMOVED]
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
提示:
- 链表中节点的数目范围是 $[0, 10^4]$
- $-10^5 \le Node.val \le 10^5$
pos
为-1
或者链表中的一个 有效索引 。
题解:
快慢指针。
设两个指针 s
和 f
分别表示快慢指针,s
每次走一步,f
每次走两步,如果链表没环,那么 f
直接走到链表末尾空指针。如果有环,当s
走到环的入口处时,假设 f
距离环的起点还需要 x
步,那么 s
再走 x
步,f
和 s
即可相遇。
时间复杂度:$O(n)$
额外空间复杂度:$O(1)$
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
if ( !head || !head->next ) return false;
ListNode *s = head, *f = head->next;
while ( s != f ) {
if ( !f || !f->next ) return false;
s = s->next;
f = f->next->next;
}
return true;
}
};
/*
时间:4ms,击败:99.56%
内存:7.8MB,击败:74.56%
*/