# [141] 环形链表

给定一个链表,判断链表中是否有环。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

示例 1:

输入:head = [3,2,0,-4], pos = 1

输出:true

解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

输入:head = [1,2], pos = 0

输出:true

解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

输入:head = [1], pos = -1

输出:false

解释:链表中没有环。

进阶:

你能用 O(1)(即,常量)内存解决此问题吗?

这道题如果不限制空间复杂度可以参考图的遍历,额外拿出一个空间为n的哈希表,每遍历到一个值就查表当前节点是否已被记录过,若没有则记录当前节点,若有则当前节点一定为环的起始点,这样就可以很轻松地测出链表中有环了。代码很简单就不列出了。

但题目要求空间复杂度为O(1),并且也不需要知道环的起始点位置。

我们知道,避免遍历在环中死循环除了可以用哈希表记录的方式,还可以用快慢指针记录的方式。慢指针一个一个遍历,快指针两个两个遍历,只要存在环,那么快慢指针一定有机会相遇。若快指针指向了null,说明链表能被遍历完,那么一定不存在环。

function hasCycle(head: ListNode | null): boolean {
  let quick = head;
  let slow = head;
  while (quick && quick.next) {
    quick = quick.next.next;
    slow = slow.next;
    if (slow === quick) {
      return true;
    }
  }
  return false;
}