判读一个链表中有没有环。
这是一道简单题,但是我做起来却不觉得简单。最初的路走偏了,想着要将链表转换为数组再判断,导致后来只能查看大神们的解法才AC。
正确的解法是双指针,一快一慢,快的指针一次走两个结点,慢的指针一次走一个结点。快的指针每次都比慢的指针多一个节点。
while
循环的终止条件有两个,
- fast指针没有下一个结点或者不能走两个结点了,这说明没有环,返回
false
- 如果有环,则终有一刻,两个指针“行走”在环上,慢的指针会被快的指针“套圈”,即慢的指针被快的指针超过一圈。
即使圈很小,而圈前的路太长,也只是快指针先在圈上跑了几圈,他们终会相遇。但如果快指针每次超过慢指针的结点数不是1,那么可能就跳过去了。
static int x = [] () {ios::sync_with_stdio(false); cin.tie(0); return 0;} ();
class Solution {
public:
bool hasCycle(ListNode *head) {
// two pointers
ListNode *slow = head, *fast = head;
while (fast) {
if (!fast->next)
return false;
fast = fast->next->next;
slow = slow->next;
if (fast == slow)
return true; // 只要有环,两个指针必有相遇的时候
}
return false;
}
};