algorighm/top-interview-leetcode150/divide/23合并k个升序列表.js

113 lines
2.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode[]} lists
* @return {ListNode}
*/
const mergeKLists = function (lists) {
};
function ListNode(val, next) {
this.val = (val === undefined ? 0 : val);
this.next = (next === undefined ? null : next);
}
/*
定义一个minIndex变量来记录当前最小头节点的索引。
在每次循环中遍历lists数组找到当前最小头节点的索引minIndex。
如果找到的minIndex为-1说明没有更多的节点可以合并跳出循环。
如果找到的minIndex不为-1将当前最小头节点添加到合并后的链表中。
然后将lists[minIndex]指向下一个节点,继续下一轮循环。
*/
/**
* 合并k个升序链表
* @param {ListNode[]} lists
* @return {ListNode}
*/
function f1(lists) {
const dummy = new ListNode(0);
let current = dummy;
// 遍历lists找到最小的头节点
while (true) {
let minIndex = -1;
for (let i = 0; i < lists.length; i++) {
if (lists[i] && (minIndex === -1 || lists[i].val < lists[minIndex].val)) {
minIndex = i; // 更新最小头节点的索引
}
}
if (minIndex === -1) break; // 没有找到最小的头节点
current.next = lists[minIndex]; // 拼接到dummy节点上
current = current.next; // 移动到下一个节点
lists[minIndex] = lists[minIndex].next; // 移动到下一个头节点
}
return dummy.next; // 返回合并后的链表
}
/*
定义一个ans表示要返回的链表然后将lists中的链表挨个和它合并最终返回ans
*/
function f2(lists) {
let ans = null;
for (let i = 0; i < lists.length; i++) {
ans = mergeLists(ans, lists[i]);
}
return ans;
}
/*
使用分治法
*/
function f3(lists) {
return merge(lists, 0, lists.length - 1);
}
/**
* @param {ListNode[]} lists 链表数组
* @param {number} l 要进行合并的左边界
* @param {number} r 要进行合并的右边界
* merge函数会将l到r范围的链表合并成一个新链表
*/
function merge(lists, l, r) {
// 如果l和r相等表明这个范围只有一个链表直接返回
if (l === r) return lists[l];
if (l > r) return null;
// 将l到r的范围拆分成左右两部分等这两部分merge之后再合并它们
const mid = Math.floor((l + r) / 2);
return mergeLists(merge(lists, l, mid), merge(lists, mid + 1, r));
}
function mergeLists(l1, l2) {
if (l1 === null || l2 === null) {
return l1 === null ? l2 : l1;
}
const dummy = new ListNode(0);
let cur = dummy;
while (l1 && l2) {
if (l1.val <= l2.val) {
cur.next = l1;
l1 = l1.next;
} else {
cur.next = l2;
l2 = l2.next;
}
cur = cur.next; // 移动到下一个节点
}
cur.next = l1 === null ? l2 : l1; // 将剩余的节点拼接到链表后面
return dummy.next; // 返回合并后的链表
}