【链表】
合并 k 个有序链表:
🌟 想办法从一堆节点中找到最小的那个节点
看了很多题解,主要是以下四种方法(优先队列我还没有写出来,先遗留着):
✔ 顺序合并
✔ 分治合并(归并)
✔ 暴力求解
✔ 优先队列
LeetCode303
链接:
23.合并 k 个升序链表
题目:
思路1 - 顺序合并:
-> 每次都看作合并两个有序链表,就是去遍历一遍链表数组,其余和 21.合并两个有序链表 同
代码:
var mergeKLists = function(lists) {
let ans = null
// 顺序去拿每个链表,两两合并,合完作为一个新数组,再跟下一个数组合并
for(let i=0; i<lists.length; i++) {
ans = mergeTwoLists(ans, lists[i])
}
return ans
};
// 第21题合并两个数组的方法
var mergeTwoLists = function(a, b) {
if(a == null || b == null) {
return a != null ? a : b
}
const dummy = new ListNode(-1)
let p = dummy, aPtr = a, bPtr = b
while(aPtr != null && bPtr != null) {
if(aPtr.val < bPtr.val) {
p.next = aPtr
aPtr = aPtr.next
} else {
p.next = bPtr
bPtr = bPtr.next
}
p = p.next
}
p.next = aPtr!==null ? aPtr : bPtr
return dummy.next
}
思路2 - 分治合并(归并):
-> 同思路1一样,每次都看作合并两个有序链表,但不是按顺序的两两合并,这里用到了递归,分组合并链表,比上一种方法在时间上会更快一些
代码:
var mergeKLists = function(lists) {
return merge(lists, 0, lists.length-1)
};
// 分治思想
var merge = function(lists, l, r) {
if(l===r) {
return lists[l]
}
if(l>r) {
return null
}
let mid = (l+r) >> 1
return mergeTwoLists(merge(lists, l, mid), merge(lists, mid+1, r))
};
// 第21题合并两个数组的方法
var mergeTwoLists = function(a, b) {
if(a == null || b == null) {
return a != null ? a : b
}
const dummy = new ListNode(-1)
let p = dummy, aPtr = a, bPtr = b
while(aPtr != null && bPtr != null) {
if(aPtr.val < bPtr.val) {
p.next = aPtr
aPtr = aPtr.next
} else {
p.next = bPtr
bPtr = bPtr.next
}
p = p.next
}
p.next = aPtr!==null ? aPtr : bPtr
return dummy.next
}
思路3 - 暴力求解:
-> 把所有链表的值拿出来放到一个数组里去,数组升序排序,再把数组的值连成一个新的链表
代码:
var mergeKLists = function(lists) {
// 定义一个数组存储所有链表的值
const temp = []
if(lists.length === 0) return null
for(let i=0; i<lists.length; i++) {
// 去遍历每个内部数组,只要有值就push到数组中
while(lists[i]) {
temp.push(lists[i].val)
lists[i] = lists[i].next // 这个其实就相当于i++
}
}
// 时刻提防空数组 二维空数组也是
if(temp.length === 0) return null
// 升序排序 其实括号里不写也没事 默认升序
temp.sort((a,b) => a-b);
// 数组排好序了 再把它们变成一个新链表
// 还是跟之前一样 定义一个哑结点
const muddy = new ListNode(-1)
// p是游标
let p = muddy
for(let i=0; i<temp.length; i++) {
// 依次把数组的值实例化为链表节点,赋值给p.next,然后p指针后移
p.next = new ListNode(temp[i])
p = p.next
}
return muddy.next
};
写在最后:
js知识还不大够,优先队列暂时先得遗留着
加油叭!