方法一:哈希表
我们可以通过检查一个结点此前是否被访问过来判断链表是否为环形链表。常用的方法是使用哈希表。
时间复杂度:O(n)O(n),对于含有 nn 个元素的链表,我们访问每个元素最多一次。添加一个结点到哈希表中只需要花费 O(1)O(1) 的时间。
空间复杂度:O(n)O(n),空间取决于添加到哈希表中的元素数目,最多可以添加 nn 个元素。
方法二:双指针
想象一下,两名运动员以不同的速度在环形赛道上跑步会发生什么?
通过使用具有 不同速度 的快、慢两个指针遍历链表,空间复杂度可以被降低至 O(1)O(1)。慢指针每次移动一步,而快指针每次移动两步。
如果列表中不存在环,最终快指针将会最先到达尾部,此时我们可以返回 false
而快跑者最终一定会追上慢跑者
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 bool hasCycle(ListNode *head) { 12 ListNode* fptr=head; 13 ListNode* lptr=head; 14 while(fptr!=nullptr && fptr->next !=nullptr){ 15 fptr=fptr->next->next; 16 lptr=lptr->next; 17 if(fptr==lptr) return true; 18 } 19 return false; 20 } 21 };