【每天学习一点算法 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)

相关推荐
田径他爸来了6 分钟前
嵌入式学习第30天——软中断,Ip进程间的通信
学习
happyprince1 小时前
01-整体观-Codex全貌解读(源码)
算法·ai编程
俊基科技1 小时前
别自己写算法了,让这颗37.5毫米的模组替你“闭嘴干活”
神经网络·算法·硬件开发·ai降噪·语音模块·回音消除
_Narcissus_2 小时前
动态规划初探(含完整代码实现)
c语言·数据结构·c++·算法·动态规划·背包问题·最短路径
白猫不黑2 小时前
网络安全/信息安全专业学习路线与入行指南:从大学到岗位的完整规划
网络·学习·安全·web安全·网络安全·黑客技术
世人万千丶2 小时前
鸿蒙项目实战 - 社区活动编排板:标签云布局算法与自动换行
学习·算法·华为·harmonyos·鸿蒙
zander2582 小时前
LeetCode 279. 完全平方数
算法·深度优先
MartinYeung52 小时前
[论文学习]AutoMalTool:基于模型上下文协议工具的LLM智能体自动红队测试
学习
典典分享指南3 小时前
VS Code Git 工作树:解锁多分支并行开发新体验
算法·决策树·逻辑回归·启发式算法