var mergeKLists = function(lists) {
if (lists.length === 0) return null;
return mergeArr(lists);
};
function mergeArr(lists) {
if (lists.length <= 1) return lists[0];
let index = Math.floor(lists.length / 2);
const left = mergeArr(lists.slice(0, index))
const right = mergeArr(lists.slice(index));
return merge(left, right);
};
function merge(l1, l2) {
if (l1 == null && l2 == null) return null;
if (l1 != null && l2 == null) return l1;
if (l1 == null && l2 != null) return l2;
let newHead = null, head = null;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
if (!head) {
newHead = l1;
head = l1;
} else {
newHead.next = l1;
newHead = newHead.next;
}
l1 = l1.next;
} else {
if (!head) {
newHead = l2;
head = l2;
} else {
newHead.next = l2;
newHead = newHead.next;
}
l2 = l2.next;
}
}
newHead.next = l1 ? l1 : l2;
return head;
};
//自顶而下归并 先分在合
var mergeKLists = function (lists) {
// 当是空数组的情况下
if (!lists.length) {
return null;
}
// 合并两个排序链表
const merge = (head1, head2) => {
let dummy = new ListNode(0);
let cur = dummy;
// 新链表,新的值小就先接谁
while (head1 && head2) {
if (head1.val < head2.val) {
cur.next = head1;
head1 = head1.next;
} else {
cur.next = head2;
head2 = head2.next;
}
cur = cur.next;
}
// 如果后面还有剩余的就把剩余的接上
cur.next = head1 == null ? head2 : head1;
return dummy.next;
};
const mergeLists = (lists, start, end) => {
if (start + 1 == end) {
return lists[start];
}
// 输入的k个排序链表,可以分成两部分,前k/2个链表和后k/2个链表
// 如果将这前k/2个链表和后k/2个链表分别合并成两个排序的链表,再将两个排序的链表合并,那么所有链表都合并了
let mid = (start + end) >> 1;
let head1 = mergeLists(lists, start, mid);
let head2 = mergeLists(lists, mid, end);
return merge(head1, head2);
};
return mergeLists(lists, 0, lists.length);
};
//自底而上合并
var mergeKLists = function (lists) {
if (lists.length <= 1) return lists[0] || null;//当归并的节点只有一个时 返回这个节点
const newLists = [];
//自底而上归并,第一次归并大小为2的链表,第二次归并大小4的链表...
for (let i = 0; i < lists.length; i += 2) {
newLists.push(merge(lists[i], lists[i + 1] || null));
}
return mergeKLists(newLists);
};
const merge = (list_1, list_2) => {//合并两个有序链表
const dummyNode = new ListNode(0);
let p = dummyNode;
while (list_1 && list_2) {
if (list_1.val < list_2.val) {//先将小的节点加入
p.next = list_1;
list_1 = list_1.next;
} else {
p.next = list_2;
list_2 = list_2.next;
}
p = p.next;
}
p.next = list_1 ? list_1 : list_2;//遍历完成还有节点剩余
return dummyNode.next;
};
(此文章只是为了记笔记,为了尊重作者原文详细请参考如下链接,谢谢!)
参考资源: