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

相关推荐
让学习成为一种生活方式7 小时前
苄基异喹啉生物碱糖基转移酶UGT74AN1晶体--Journal of Agricultural and Food Chemistry
人工智能·算法
早睡早起身体好1237 小时前
为什么 Network 中会出现两个同名请求?——CORS 预检请求学习笔记
网络·笔记·学习·网络安全
菩提树下的打坐7 小时前
测试左移的更深一层:用 DDD 战术设计反推测试边界
学习
alphaTao7 小时前
LeetCode 每日一题 2026/7/27-2026/8/2
python·算法·leetcode
2501_926978337 小时前
提示工程的实战报告(二):模型的失败模式与边界行为
人工智能·深度学习·算法
小小晓.7 小时前
C++记:函数
开发语言·c++·算法
casual~7 小时前
模逆元计算方法详解:扩展欧几里得算法与费马小定理
学习·算法·逆元
@Mike@8 小时前
06-数据库学习笔记(存储模型与数据压缩)
数据库·笔记·学习
脚踏实地皮皮晨8 小时前
002002002_DepandencyObject类2
开发语言·windows·算法·c#·visual studio
我的xiaodoujiao8 小时前
快速学习Python基础知识详细图文教程14--模块
开发语言·python·学习·测试工具