合并 k 个升序的链表并将结果作为一个升序的链表返回其头节点。
数据范围:节点总数
,每个节点的val满足
要求:时间复杂度
// 既然是lists是数组,那就循环遍历,每次找到链表头值最小的那个索引,在进行拼接
function mergeKLists( lists ) {
let res = new ListNode(0)
let curr = res
while(true){
let idx = -1
for(index in lists){
if(lists[index] == null) continue
else if(idx == -1) idx = index
else if(lists[index].val < lists[idx].val){
idx = index
}
}
if(idx == -1) break
curr = curr.next = lists[idx]
lists[idx] = lists[idx].next
}
return res.next
} /*
* function ListNode(x){
* this.val = x;
* this.next = null;
* }
*/
/**
*
* @param lists ListNode类一维数组
* @return ListNode类
*/
function merge( lists, left, right) {
if (left >= right)
return lists[left]
let mid = ~~((left + right) / 2);
let l = merge( lists, left, mid);//返回左区间指针
let r = merge( lists, mid + 1, right);//返回右区间指针
let head = new ListNode(-1);
let temp = head;
while (l != null && r != null) {
if (l.val <= r.val) {
temp.next = l
temp = l;
l = l.next;
} else {
temp.next = r
temp = r;
r = r.next;
}
}
if (l != null) {
temp.next = l
}
if (r != null) {
temp.next = r
}
return head.next;
}
function mergeKLists(lists) {
return merge(lists, 0, lists.length - 1);
}
module.exports = {
mergeKLists : mergeKLists
}; 主要有两个比较好的方法,一个是堆,一个是分治。
js写这个题。如果使用堆(优先队列)的话,难点是需要自己实现堆的数据结构。c或java好像都有内置已经写好的优先队列数据解构。
js利用数组实现堆需要注意的是:
function mergeKLists( lists ) {
if (lists.length <= 1) return lists[0] || null;
let heap = new minHeap(), head = {next: null}, p = head;
for (let i=0; i<lists.length; ++i) {
if (lists[i]) {
heap.push(lists[i]);
}
}
while(heap.heap.length) {
p.next = heap.pop();
p = p.next;
if (p.next) {
heap.push(p.next);
}
}
return head.next;
}
class minHeap {
constructor() {
this.heap = [];
}
push(node) {
this.heap.push(node);
let i = this.heap.length-1, dad = Math.floor((i-1)/2);
while(dad >= 0) {
this.minHeap(dad, i);
dad = Math.floor((dad-1)/2);
}
}
pop() {
const i=0, j=this.heap.length-1;
[this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]]
const res = this.heap.splice(j, 1);
this.minHeap(0, j-1);
return res[0];
}
minHeap(l, r) {
let dad = l, son = dad*2+1;
if (son > r) return;
if (son + 1 <= r && this.heap[son+1].val < this.heap[son].val) {
++son;
}
if (this.heap[son].val < this.heap[dad].val) {
[this.heap[dad], this.heap[son]] = [this.heap[son], this.heap[dad]]
this.minHeap(son, r);
}
}
}分治法:
function mergeKLists( lists ) {
if (lists.length <= 1) return lists[0] || null;
return merge(lists, 0, lists.length-1);
}
function merge(lists, l, r) {
if (l > r) return null;
if (l === r) return lists[l];
const mid = Math.floor((l+r)/2);
return mergeTwoList(merge(lists, l, mid), merge(lists, mid+1, r));
}
function mergeTwoList (list1, list2) {
if (!list1 || !list2) return list1 || list2;
let p1 = list1, p2 = list2, head = {next: null}, p = head;
while(p1 && p2) {
if (p1.val > p2.val) {
p.next = p2;
p2 = p2.next;
} else {
p.next = p1;
p1 = p1.next;
}
p = p.next;
}
p.next = p1 || p2;
return head.next;
}