「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战」
题目
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 1:
输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6
示例 2:
输入:lists = []
输出:[]
示例 3:
输入:lists = [[]]
输出:[]
提示:
- k == lists.length
- 0 <= k <= 10^4
- 0 <= lists[i].length <= 500
- -10^4 <= lists[i][j] <= 10^4
- lists[i] 按 升序 排列
- lists[i].length 的总和不超过 10^4
来源:力扣(LeetCode)leetcode-cn.com/problems/me…
解题思路
第一种思路是把数组中的链表按顺序合并; 第二种思路是通过分治的方式,把数组对半拆分,再对两边子数组分治做合并操作。直到拆分不了时,左右两个子数组中剩下一个链表,合并这两个链表为一个链表。两两合并后得到的新链表再依次往上两两合并,最终合并成一个链表。
这里我们使用第二种方式来解这道题。
代码实现
var mergeKLists = function (lists) {
return merge(lists, 0, lists.length - 1)
}
var merge = function (lists, left, right) {
if (left === right) return lists[left]
if (left > right) return null
// 从数组中间平分,通过分治的方式合并链表
const mid = (left + right) >> 1
// 合并数组左边链表
const l1 = merge(lists, left, mid)
// 合并数组右边链表
const l2 = merge(lists, mid + 1, right)
return mergeTwoList(l1, l2)
}
function mergeTwoList(l1, l2) {
if (!l1 || !l2) return l1 ? l1 : l2
const tail = new ListNode()
if (l1.val <= l2.val) {
// 如果 l1 的表头小于等于 l2 的表头,则把 l1 取出来
// 再将 l1 的 next 和 l2 合并,返回的结果再和 l1 连接
tail.next = l1
l1.next = mergeTwoList(l1.next, l2)
} else {
// 如果 l1 的表头大于 l2 的表头,则把 l2 取出来
// 再将 l2 的 next 和 l1 合并,返回的结果再和 l2 连接
tail.next = l2
l2.next = mergeTwoList(l1, l2.next)
}
//返回临时节点的下个节点
return tail.next
}
如有错误欢迎指出,欢迎一起讨论!