【经典算法题】环形链表
Leetcode 0141 环形链表
题目描述:Leetcode 0141 环形链表
分析
-
本题的考点:快慢指针。
-
使用双指针
s、f
,s
表示慢指针,每次向后移动一个位置,f
表示快指针,每次向后移动两个位置。如果存在环的话,则两个指针一定会相遇;否则不存在环。
代码
- C++
class Solution {
public:
bool hasCycle(ListNode *head) {
if (!head || !head->next) return false;
auto s = head, f = head;
while (true) {
if (!f || !f->next) return false;
s = s->next; f = f->next->next;
if (s == f) return true;
}
}
};
- Java
public class Solution {
public boolean hasCycle(ListNode head) {
if (head == null || head.next == null) return false;
ListNode s = head, f = head;
while (true) {
if (f == null || f.next == null) return false;
s = s.next; f = f.next.next;
if (s == f) return true;
}
}
}
时空复杂度分析
-
时间复杂度: O ( n ) O(n) O(n),
n
为链表长度。 -
空间复杂度: O ( 1 ) O(1) O(1)。
Leetcode 0142 环形链表 II
分析
-
本题的考点:快慢指针。
-
分析如下:
代码
- C++
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
if (!head || !head->next) return NULL;
auto s = head, f = head;
while (true) {
if (!f || !f->next) return NULL;
s = s->next, f = f->next->next;
if (s == f) break; // 第一次相遇
}
// 能运行到这里说明一定存在环
s = head;
while (s != f) s = s->next, f = f->next;
return s;
}
};
- Java
public class Solution {
public ListNode detectCycle(ListNode head) {
if (head == null || head.next == null) return null;
ListNode s = head, f = head;
while (true) {
if (f == null || f.next == null) return null;
s = s.next; f = f.next.next;
if (s == f) break;
}
s = head;
while (s != f) {
s = s.next; f = f.next;
}
return s;
}
}
时空复杂度分析
-
时间复杂度: O ( n ) O(n) O(n),
n
为链表长度。 -
空间复杂度: O ( 1 ) O(1) O(1)。