返回

TS实现:LeetCode 141 题 - 环形链表

前端

算法实现

快慢指针法

快慢指针法是一种简单而有效的算法,用于检测环形链表。该算法使用两个指针,一个称为“快指针”,另一个称为“慢指针”。快指针每次移动两个节点,而慢指针每次移动一个节点。如果链表中存在环,则快指针最终会追上慢指针。

const hasCycle = (head: ListNode | null): boolean => {
  if (!head || !head.next) {
    return false;
  }

  let slow = head;
  let fast = head.next;

  while (slow !== fast) {
    if (!fast || !fast.next) {
      return false;
    }
    slow = slow.next;
    fast = fast.next.next;
  }

  return true;
};

哈希表法

哈希表法也是一种检测环形链表的常用算法。该算法使用哈希表来存储已经访问过的节点。当访问一个新的节点时,如果该节点已经在哈希表中,则说明链表中存在环。

const hasCycle = (head: ListNode | null): boolean => {
  if (!head) {
    return false;
  }

  const visited = new Set<ListNode>();

  let current = head;

  while (current) {
    if (visited.has(current)) {
      return true;
    }
    visited.add(current);
    current = current.next;
  }

  return false;
};

进一步探索

寻找环的入口节点

如果链表中存在环,我们还可以找到环的入口节点。环的入口节点是指链表中第一个出现在环中的节点。

const findCycleEntrance = (head: ListNode | null): ListNode | null => {
  if (!head || !head.next) {
    return null;
  }

  const visited = new Set<ListNode>();

  let current = head;

  while (current) {
    if (visited.has(current)) {
      return current;
    }
    visited.add(current);
    current = current.next;
  }

  return null;
};

计算环的长度

如果链表中存在环,我们还可以计算环的长度。环的长度是指环中节点的数量。

const calculateCycleLength = (head: ListNode | null): number => {
  if (!head || !head.next) {
    return 0;
  }

  const visited = new Set<ListNode>();

  let current = head;
  let cycleLength = 0;

  while (current) {
    if (visited.has(current)) {
      break;
    }
    visited.add(current);
    current = current.next;
    cycleLength++;
  }

  return cycleLength;
};

最佳实践和注意事项

  • 在实际项目中,应根据具体情况选择合适的算法来检测环形链表。如果链表很长,则哈希表法可能更适合,因为其时间复杂度为 O(n),而快慢指针法的