返回

力扣 142:环形链表 || 代码演练和解释

前端

问题

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

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例 2:

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

解决思路

要解决这个问题,我们可以使用一种称为快慢指针算法的技术。这个算法使用两个指针:一个慢指针和一个快指针。慢指针每次移动一步,而快指针每次移动两步。如果链表中有环,那么快指针最终会赶上慢指针。

要使用快慢指针算法检测环形链表,我们可以遵循以下步骤:

  1. 初始化两个指针,慢指针和快指针,都指向链表的头部。
  2. 循环执行以下步骤,直到快指针和慢指针相遇或快指针到达链表的末尾:
    • 将慢指针移动一步。
    • 将快指针移动两步。
  3. 如果快指针到达链表的末尾,则链表没有环。
  4. 如果快指针和慢指针相遇,则链表中有环。

代码实现

JavaScript

const hasCycle = function(head) {
  if (head === null || head.next === null) {
    return false;
  }

  let slow = head;
  let fast = head;

  while (fast !== null && fast.next !== null) {
    slow = slow.next;
    fast = fast.next.next;

    if (slow === fast) {
      return true;
    }
  }

  return false;
};

Python

def has_cycle(head):
    if head is None or head.next is None:
        return False

    slow = head
    fast = head

    while fast is not None and fast.next is not None:
        slow = slow.next
        fast = fast.next.next

        if slow == fast:
            return True

    return False

Java

public boolean hasCycle(ListNode head) {
    if (head == null || head.next == null) {
        return false;
    }

    ListNode slow = head;
    ListNode fast = head;

    while (fast != null && fast.next != null) {
        slow = slow.next;
        fast = fast.next.next;

        if (slow == fast) {
            return true;
        }
    }

    return false;
}

结论

使用快慢指针算法,我们可以有效地检测环形链表。通过将一个慢指针和一个快指针移动到链表中,我们可以确定链表中是否存在环。这种算法简单易于实现,并且在时间复杂度 O(n) 和空间复杂度 O(1) 的情况下工作,其中 n 是链表中的节点数。