Leetcode 141. Linked List Cycle & 142. Linked List Cycle II
Leetcode 141. Linked List Cycle
解法一
直接给遍历过的点打标记,再回来就说明有环。
class Solution {
public:
const int N = 100005;
bool hasCycle(ListNode *head) {
ListNode *cur = head;
while(cur) {
if(cur->val == N) {
return true;
}
cur->val = N;
cur = cur->next;
}
return false;
}
};
解法二
快慢指针法,跑得快的一定会在某个时刻追上跑得慢的,详细的时间复杂度分析:
官方知乎解答
class Solution {
public:
const int N = 100005;
bool hasCycle(ListNode *head) {
ListNode *fast = head, *slow = head;
while(fast && fast->next) {
fast = fast->next->next;
slow = slow->next;
if(fast == slow) {
return true;
}
}
return false;
}
};
注意要把if(fast == slow)
的判定放在循环结束,否则一上来就会无脑return true
.
142. Linked List Cycle II
用上面的方法一可以秒杀,用快慢指针就比较麻烦了。
这里有详细的数学推导
知乎优质解答
ListNode *detectCycle_1(ListNode *head) {
ListNode *fast = head, *slow = head;
bool hasCycle = false;
while (fast && fast->next) {
fast = fast->next->next;
slow = slow->next;
if (fast == slow) {
hasCycle = true;
break;
}
}
if (!hasCycle) {
return nullptr;
}
ListNode* newStart = slow; // 新的起点
slow = head;
while(newStart != slow) {
slow = slow->next;
newStart = newStart->next;
}
return slow;
}