Leetcode 141 Linked List Cycle

判读一个链表中有没有环。

这是一道简单题,但是我做起来却不觉得简单。最初的路走偏了,想着要将链表转换为数组再判断,导致后来只能查看大神们的解法才AC。

正确的解法是双指针,一快一慢,快的指针一次走两个结点,慢的指针一次走一个结点。快的指针每次都比慢的指针多一个节点。

while循环的终止条件有两个,

  1. fast指针没有下一个结点或者不能走两个结点了,这说明没有环,返回false
  2. 如果有环,则终有一刻,两个指针“行走”在环上,慢的指针会被快的指针“套圈”,即慢的指针被快的指针超过一圈。

即使圈很小,而圈前的路太长,也只是快指针先在圈上跑了几圈,他们终会相遇。但如果快指针每次超过慢指针的结点数不是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;
  }
};

#直达链接

LeetCode 141. Linked List Cycle