本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
输入: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
题目解析
思路一
通过一次拿出两个数组元素,合并成一个新元素之后存放到新数组中,全部遍历后,再将新数组再次迭代,然后再通过数组元素判断, for循环中i每次加二,在最后时,数组长度如果为偶数,刚好有两个元素可以进行合并;如果为基数,判断i与长度大小,大于等于时说明为奇数,l2需要赋值为null。完成后继续迭代。
var mergeKLists = function(lists) {
// 如为空数组直接返回
if (!lists.length) return null;
// 数组长度为一也可直接返回,这也是大多数情况的返回条件
if (lists.length == 1) return lists[0];
// newLists是新数组,迭代用
let newLists = [], l2;
for(let i = 0; i < lists.length; i = i + 2){
let l1 = lists[i];
// 判断长度是否为奇, 奇数则l2需赋值为null
if(i < lists.length - 1){
l2 = lists[i+1];
}else {
l2 = null;
}
// 新数组插入新元素
newLists.push(mergeTwoLists(l1, l2));
}
// 迭代
return mergeKLists(newLists);
};
//尾插法合并两个链表
function mergeTwoLists(l1, l2) {
let head = new ListNode(), pre = head
while (l1 && l2) {
if (l1.val > l2.val) {
pre.next = l2;
l2 = l2.next;
} else {
pre.next = l1;
l1 = l1.next;
}
pre = pre.next;
}
pre.next = l1 ? l1 : l2;
return head.next;
};
思路二
暴力解法,将所有的链表节点数字加到数组里,然后利用数组排序,之后生成新的链表。
var mergeKLists = function(lists) {
let nums = [];
// 将所有的链表节点上的数都加到数组里
for(let list of lists){
while(list!=null){
nums.push(list.val);
list = list.next;
}
}
// 排序
nums.sort((a,b)=>a-b);
// 生成新的链表
const newNode = new ListNode(nums[0]);
// 保存地址
let root = newNode;
// 循环数组,将每个数字加入新链表
for(let i = 0;i<nums.length;++i){
const node = new ListNode(nums[i]);
// 加入链表末尾
root.next = node;
// 往后移
root = root.next;
}
// 第一个节点是多余的,不需要
return newNode.next;
};