[路飞]_前端算法第六十六弹-数组中的第K个最大元素

96 阅读1分钟

给定整数数组 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

这是一道典型的利用堆与队列的题。求第K大的元素,应该使用小顶堆来实现,具体小顶堆的实现我在上一篇文章里有写。所以这里我们直接使用。我们先写一个小顶堆。

class SmallHeap {

    constructor() {
        this.cmp = new Array();
        this.count = 0;
    }

    push(x) {
        let cmp = this.cmp
        cmp[this.count] = x;
        let index = this.count;
        this.count++;
        let pre = Math.floor((index - 1) / 2);
        while (index != 0 && cmp[pre] > x) {
            [cmp[pre], cmp[index]] = [cmp[index], cmp[pre]]
            index = pre
            pre = Math.floor((index - 1) / 2);
        }
        this.cmp = cmp
        return;
    }

    pop() {
        if (this.size() == 0) return;
        let cmp = this.cmp;
        let num = cmp[0];
        [cmp[0], cmp[this.count - 1]] = [cmp[this.count - 1], cmp[0]];
        this.count--;
        let index = 0;
        let n = this.count - 1;
        while (index * 2 + 1 <= n) {
            let temp = index;
            if (cmp[temp] > cmp[index * 2 + 1]) temp = index * 2 + 1;
            if (index * 2 + 2 <= n && cmp[temp] > cmp[index * 2 + 2]) temp = index * 2 + 2;
            if (cmp[temp] == cmp[index]) break;
            [cmp[temp], cmp[index]] = [cmp[index], cmp[temp]];
            index = temp
        }
        this.cmp = cmp;
        return num;
    }

    top() {
        return this.cmp[0]
    }

    size() {
        return this.count;
    }

}

然后我们对nums进行入队,我们需要找出第K大的元素,只需要在队列中一直保持有k个元素即可。

var findKthLargest = function (nums, k) {
    let heap = new SmallHeap();
    for (let i = 0; i < nums.length; i++) {
        heap.push(nums[i])
        if (i >= k) {
            heap.pop()
        }
    }
    return heap.top()
};