215. 数组中的第K个最大元素(medium) -力扣(leetCode)逆流而上,JS小根堆

⚡️215. 数组中的第K个最大元素⚡️
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5

示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4

提示:
1 <= k <= nums.length <= 104
-104 <= nums[i] <= 104

⚡️分析⚡️

第K个最大元素,那么我们可以通过对现有数组进行快排,然后找第K个最大元素;也可以通过堆的数据结构来找。
这里我通过小根堆的方法来解题。将现有数组中的元素一个个插入堆中,在每次插入后都对堆进行排序使得为小根堆,当插入后堆的数组长度大过题目给的k值,那么就将堆顶(最小值)给弹出(弹出后也要重新排序使得为小根堆)。
举个例子:当堆中有[5,6],5为第二大元素,然后插入一个4,即插入到堆顶,那么长度大过题目要求的k值2了,那么就把4弹出,堆顶仍然符合题意,第k大的元素为堆顶的5.

代码如下:

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] > this.heap[index]){
            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[index] > this.heap[left]){
            this.swap(index,left);
            this.shiftdown(left);
        }
        if(this.heap[index] > this.heap[right]){
            this.swap(index,right);
            this.shiftdown(right);
        }
    }

    pop(){
        this.heap[0] =  this.heap.pop();
        this.shiftdown(0);
    }

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

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

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
var findKthLargest = function(nums, k) {
    const heap = new MinHeap();
    nums.forEach(item => {
        heap.insert(item);
        if(heap.Length() > k){
            heap.pop();
        }
    })
    return heap.popout();
};

算法效率如图:
在这里插入图片描述




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

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值