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