【每天学习一点算法 2026/05/10】合并K个排序链表

每天学习一点算法 2026/05/10

题目:合并K个排序链表

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

最简单的办法就是一个一个的合并链表即可,具体做法就是新建一个链表作为合并结果链表表头,维护两个指针指向两个链表的表头,比较指针对应节点的 val ,将较小值作为合并结果的下一个节点,并移动指针。

typescript 复制代码
function mergeKLists(lists: Array<ListNode | null>): ListNode | null {
  // 链表合并方法
  function mergeTwoLists (listA: ListNode | null, listB: ListNode | null) {
    // 当合并的其中一个链表为空时,直接返回另一个链表
    if (!listA || !listB) return listA ? listA : listB
    const head =  new ListNode(0) // 新建一个链表
    let tail = head // 合并结果指针, 初始指向 head
    // 当合并的两个链表都还有剩余节点时循环
    while (listA && listB) {
      // 比较两个链表当前节点值大小
      if (listA.val > listB.val) {
        tail.next = listB
        listB = listB.next
      } else {
        tail.next = listA
        listA = listA.next
      }
      // 更新合并节点指针
      tail = tail.next
    }
    // 当某一个链表合并完毕,处理剩余节点
    tail.next = listA ? listA : listB
    // 返回合并后链表表头
    return head.next
  }

  let res = null
  // 合并所有链表
  for (let i = 0; i < lists.length; i++) {
    res = mergeTwoLists(res, lists[i])
  }

  return res
};

针对上面的方法我们可以做一下优化,我们可以利用的分治的思想,将链表两两配对合并,得到的结果再两两配对合并直至只剩一个链表,这里我们利用递归来实现。

typescript 复制代码
function mergeKLists(lists: Array<ListNode | null>): ListNode | null {
  function mergeTwoLists (listA: ListNode | null, listB: ListNode | null) {
    if (!listA || !listB) return listA ? listA : listB
    const head =  new ListNode(0)
    let tail = head
    while (listA && listB) {
      if (listA.val > listB.val) {
        tail.next = listB
        listB = listB.next
      } else {
        tail.next = listA
        listA = listA.next
      }
      tail = tail.next
    }
    tail.next = listA ? listA : listB
    return head.next
  }
  // 合并方法
  function merge (lists: Array<ListNode | null>, left: number, right: number): ListNode {
    if (left === right) return lists[left] // 两指针相遇返回所指的链表
    if (left > right) return null // 超出边界返回 null
    const mid = Math.floor((left + right) / 2) // 取中间值进行分治
    // 递归合并分组合并结果
    return mergeTwoLists(merge(lists, left, mid), merge(lists, mid + 1, right))
  }

  return merge(lists, 0, lists.length - 1)
};

题目来源:力扣(LeetCode)

相关推荐
JieE2129 小时前
LeetCode 101. 对称二叉树|JS 递归 + 迭代双解法,彻底搞懂镜像判断
javascript·算法
JieE2121 天前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack202 天前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树2 天前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色
JieE2122 天前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法
JieE2122 天前
LeetCode 104. 二叉树的最大深度|递归思路超详细拆解
javascript·算法
vivo互联网技术3 天前
CVPR 2026 | 全新强化学习框架 BeautyGRPO:重塑真实人像
算法·大模型·cvpr·影像
Darling噜啦啦3 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
用户497863050733 天前
(一)小红的数组操作
算法·编程语言