Problem: 141. 环形链表
方法一:哈希集合
思路
使用一个哈希集合记录链表中的所有结点,当遍历过程中如果出现重复元素,则说明链表中存在环,返回true。
Code
/**
* 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) {
unordered_set<ListNode*> set;
while(head){
if(set.count(head)){
return true;
}
set.insert(head);
head = head->next;
}
return false;
}
};
复杂度
-
时间复杂度:
O ( n ) O(n) O(n),n为链表长度。 -
空间复杂度:
O ( n ) O(n) O(n),n为链表长度。
方法二:快慢指针
思路
想象你在操场上跑步,如果你跑100米,那跑的快的同学和你永远不会相遇。
如果是绕圈跑1000米,你还在跑第一圈,他已经在跑第二圈了。
特殊地,我们安排两位运动员不在同一起点,则当他们相遇时即认为存在环。
综上,我们设置2个指针slow、fast设置在不同起点,若快指针已经走完,则链表中不存在环。若快慢指针相同,则说明存在环。
Code
/**
* 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 == nullptr)
return false;
ListNode* slow = head, *fast = head->next;
while(fast && fast->next){
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
return true;
}
return false;
}
};
复杂度
-
时间复杂度:
O ( n ) O(n) O(n),n为链表长度。 -
空间复杂度:
O ( 1 ) O(1) O(1)