返回

微观审视链表——21. 合并两个有序链表

闲谈

链表简介

链表是一种线性数据结构,由一个个节点组成,每个节点包含数据和指向下一个节点的指针。链表具有插入和删除操作的效率高、空间利用率高等优点,广泛应用于各种场景。

合并两个有序链表

合并两个有序链表是指将两个已经按升序排列的链表合并成一个新的有序链表。

算法实现

递归实现

def merge_two_sorted_lists(l1, l2):
  """
  合并两个有序链表。

  Args:
    l1: 第一个链表。
    l2: 第二个链表。

  Returns:
    合并后的链表。
  """

  # 如果l1为空,直接返回l2。
  if not l1:
    return l2

  # 如果l2为空,直接返回l1。
  if not l2:
    return l1

  # 如果l1的第一个节点的值小于l2的第一个节点的值,则将l1的第一个节点作为合并后的链表的第一个节点,并递归合并l1的其余部分和l2。
  if l1.val < l2.val:
    new_head = l1
    new_head.next = merge_two_sorted_lists(l1.next, l2)
  # 否则,将l2的第一个节点作为合并后的链表的第一个节点,并递归合并l1和l2的其余部分。
  else:
    new_head = l2
    new_head.next = merge_two_sorted_lists(l1, l2.next)

  return new_head

迭代实现

def merge_two_sorted_lists(l1, l2):
  """
  合并两个有序链表。

  Args:
    l1: 第一个链表。
    l2: 第二个链表。

  Returns:
    合并后的链表。
  """

  # 创建一个新的链表,作为合并后的链表的头部。
  new_head = ListNode(0)

  # current指针指向合并后的链表的当前位置。
  current = new_head

  # while循环,直到l1和l2都为空。
  while l1 and l2:
    # 如果l1的第一个节点的值小于l2的第一个节点的值,则将l1的第一个节点添加到合并后的链表中,并更新l1。
    if l1.val < l2.val:
      current.next = l1
      l1 = l1.next
    # 否则,将l2的第一个节点添加到合并后的链表中,并更新l2。
    else:
      current.next = l2
      l2 = l2.next

    # 更新current指针。
    current = current.next

  # 将剩余的l1或l2添加到合并后的链表中。
  if l1:
    current.next = l1
  if l2:
    current.next = l2

  # 返回合并后的链表。
  return new_head.next

复杂度分析

时间复杂度

  • 最坏情况下,两个链表交错,直到一个为空。
  • 时间复杂度:O(n + m)

空间复杂度

  • 没有使用额外空间。
  • 空间复杂度:O(1)

应用场景

链表合并算法在实际中有很多应用场景,例如:

  • 将两个有序数组合并成一个有序数组。
  • 将两个有序文件合并成一个有序文件。
  • 将两个有序队列合并成一个有序队列。

总结

链表合并算法是一种非常重要的算法,具有广泛的应用场景。通过将两个有序链表合并成一个有序链表,我们可以提高数据的处理效率,并简化算法的实现。