返回

剖析剑指 Offer II 023:巧妙解题,寻找两个链表的重合节点

闲谈

导言:

在计算机科学领域,链表是一种常见的数据结构,它由一系列相互连接的节点组成,每个节点包含数据和指向下一个节点的指针。链表广泛应用于各种算法和数据结构中,例如栈、队列和哈希表。

剑指 Offer II 023 题要求我们找到两个链表的第一个重合节点。这个问题在编程面试中经常出现,因为它考察了程序员对链表的基本理解和算法实现能力。

方法一:哈希表法

哈希表是一种数据结构,它利用哈希函数将键值对映射到一个固定大小的数组中。哈希表以其快速的查找和插入操作而闻名,因此它非常适合用于寻找链表的重合节点。

算法步骤:

  1. 创建一个哈希表,将第一个链表的节点逐一插入哈希表中。
  2. 遍历第二个链表,检查每个节点是否在哈希表中。
  3. 如果找到一个节点在哈希表中,则该节点就是两个链表的第一个重合节点。
  4. 如果遍历完第二个链表都没有找到重合节点,则说明两个链表没有交点。

代码示例:

def find_first_common_node(headA, headB):
  """
  哈希表法寻找两个链表的第一个重合节点

  Args:
    headA: 第一个链表的头节点
    headB: 第二个链表的头节点

  Returns:
    两个链表的第一个重合节点,如果不存在则返回None
  """

  # 创建一个哈希表来存储第一个链表的节点
  hash_table = {}
  current_node = headA
  while current_node is not None:
    hash_table[current_node] = True
    current_node = current_node.next

  # 遍历第二个链表,检查每个节点是否在哈希表中
  current_node = headB
  while current_node is not None:
    if current_node in hash_table:
      return current_node
    current_node = current_node.next

  # 如果遍历完第二个链表都没有找到重合节点,则说明两个链表没有交点
  return None

方法二:双指针法

双指针法是一种解决链表问题的经典方法。它使用两个指针同时遍历两个链表,当两个指针相遇时,说明两个链表存在重合节点。

算法步骤:

  1. 将两个指针分别指向两个链表的头节点。
  2. 同时遍历两个链表,每次将两个指针都向后移动一步。
  3. 如果两个指针在某个节点相遇,则该节点就是两个链表的第一个重合节点。
  4. 如果遍历完两个链表,两个指针都没有相遇,则说明两个链表没有交点。

代码示例:

def find_first_common_node(headA, headB):
  """
  双指针法寻找两个链表的第一个重合节点

  Args:
    headA: 第一个链表的头节点
    headB: 第二个链表的头节点

  Returns:
    两个链表的第一个重合节点,如果不存在则返回None
  """

  # 将两个指针分别指向两个链表的头节点
  pointerA = headA
  pointerB = headB

  # 同时遍历两个链表,每次将两个指针都向后移动一步
  while pointerA is not None and pointerB is not None:
    if pointerA == pointerB:
      return pointerA
    pointerA = pointerA.next
    pointerB = pointerB.next

  # 如果遍历完两个链表,两个指针都没有相遇,则说明两个链表没有交点
  return None

总结:

在本文中,我们介绍了两种方法来寻找两个链表的第一个重合节点:哈希表法和双指针法。这两种方法各有优缺点,哈希表法的时间复杂度为 O(n),空间复杂度为 O(n),而双指针法的時間复杂度为 O(n),空間复杂度为 O(1)。您可以根据实际情况选择合适的方法来解决这个问题。