23. 合并K个升序链表(hard) -力扣(leetCode)JS小根堆

⚡️23. 合并K个升序链表⚡️
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:
输入: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

示例 2:
输入:lists = []
输出:[]

示例 3:
输入:lists = [[]]
输出:[]

提示:
k == lists.length
0 <= k <= 10^4
0 <= lists[i].length <= 500
-10^4 <= lists[i][j] <= 10^4
lists[i] 按 升序 排列
lists[i].length 的总和不超过 10^4

⚡️分析⚡️

先将所有链表压入堆,比较各链表第一个结点来进行堆排序,然后通过比较各链表第一个结点来决定压入哪个到新链表,直到堆空为止(即所有链表都无结点)。

代码如下:

class MinHeap {
    constructor(){
        this.heap = [];
    }

    fatherIndex(index){
        return (index-1) >> 1;
    }

    swap(a,b){
        const res = this.heap[a];
        this.heap[a] = this.heap[b];
        this.heap[b] = res;
    }

    shiftup(index){
        if(index == 0)return;
        const father = this.fatherIndex(index);
        if(this.heap[father].val > this.heap[index].val){
            this.swap(father , index);
            this.shiftup(father);
        }
    }

    insert(value){
        this.heap.push(value);
        this.shiftup(this.heap.length-1);
    }

    shiftdown(index){
        if(index >= this.heap.length)return;
        const left = index*2+1;
        const right = index*2+2;
        if(this.heap[left] && this.heap[index].val > this.heap[left].val){
            this.swap(index,left);
            this.shiftdown(left);
        }
        if(this.heap[right] && this.heap[index].val > this.heap[right].val){
            this.swap(index,right);
            this.shiftdown(right);
        }
    }

    pop(){
        if(this.Length() === 1)return this.heap.shift();
        const top = this.heap[0];
        this.heap[0] =  this.heap.pop();
        this.shiftdown(0);
        return top;
    }

    Length(){
        return this.heap.length;
    }

    
    popout(){
        return this.heap[0];
    }
}

/**
 * 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}
 */
var mergeKLists = function(lists) {
    const res = new ListNode(0);
    let p = res;
    const h = new MinHeap();
    lists.forEach(item => {
        if(item)
            h.insert(item)
    });
    while(h.Length()){
        const q = h.pop();
        p.next = q;
        p = p.next;
        if(q.next)
            h.insert(q.next)
    }

    return res.next;
};

算法效率如图:
23. 合并K个升序链表(hard) -力扣(leetCode)JS小根堆_第1张图片




觉得该篇文章有用的请不要忘记忘记点击右下角的大拇指~

欢迎大家关注我的公众号:Smooth前端成长记录
公众号正在努力更新CSDN博客内容,想方便阅读博客的C友可以来关注我的公众号以便获得更优良的阅读体验~
在这里插入图片描述

你可能感兴趣的:(leetcode力扣,链表,算法,leetcode,js,堆排序)