LeetCode 141环形链表
-
题目简述:给定一个链表,判断链表中是否有环。为了表示给定链表中的环,我们使用整数
pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果pos
是-1
,则在该链表中没有环。 -
输入:head = [3,2,0,-4], pos = 1 输出:true(-4指向2)
输入:head = [1,2], pos = 0 输出:true(2指向1)
输入:head = [1], pos = -1 输出:false(无环)
-
双指针解法:用两个指针从头开始扫描,慢指针每次走一步,快指针每次走两步。如果走到
null
,说明不存在环;否则如果两个指针相遇,则说明存在环。解释:假设链表存在环,则当慢指针走到环入口时,快指针已经走到环上的某个位置,距离环入口还差
x
步。由于快指针每次比慢指针多走一步,所以慢指针再走x
步两个指针就会相遇如果有环快指针走的路程是慢指针的两倍,总时间复杂度是
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;
auto slow = head, fast = head->next;
while(slow != fast)
{
if(!fast || !fast->next) return false;
slow = slow->next;
fast = fast->next->next;
}
return true;
}
};
- 哈希表解法:通过哈希表检查一个结点此前是否被访问过来判断链表是否为环形链表。遍历所有链表节点哈希表存储每个节点信息,如果当前节点是空节点,即已经检测到链表尾部节点的下一节点,则该链表不是环形链表,返回
false
;如果当前节点已经在哈希表中,那么该链表是环形链表,返回true
。 - 每次遍历需要将每一个链表节点加入哈希表中,时间复杂度
O(n)
,空间复杂度O(n)
class Solution {
public:
bool hasCycle(ListNode *head) {
unordered_map<ListNode *, bool> hash;
while(head != NULL)
{
if(hash[head]) return true;
else hash[head] = true;
head = head->next;
}
return false;
}
};