Leetcode 215. Kth Largest Element in an Array

本文介绍几种高效查找未排序数组中第K大元素的方法,包括使用最小堆、最大堆及快速选择算法。通过实例演示了不同算法的具体实现,并对比了它们的时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

For example,
Given [3,2,1,5,6,4] and k = 2, return 5.

Note:
You may assume k is always valid, 1 ≤ k ≤ array’s length.

s思路:
1. 如果k等于1,表示最大值,就有o(n)的做法。如果k为5,怎么办?想想在,k=1时,每次比较把最大的留下,也就是只需要存一个最大的candidate;k=5,也就是我们至少需要存5个candidate才可以。
2. 当然这道题,简单粗暴的是全排序然后找到k大的值,这样就是o(nlgn)。有个经验是,找k大的,用priority_queue来做。
3. 比如,这道题,由于只需要保存k个candidate,所以需要k长的priority_queue。用前k个数来初始化priority_queue,然后每次放入一个,取出一个,由于用的是minimum binary heap,每次取出都是最小值,所以最后留下k个最大值,而顶上的就是第k大的值。复杂度的话,由于priority_queue长度为k,每次操作都是o(lgk),一共操作n次,因此o(nlgk).
4. 再试一试用max-heap的方法。用max-heap的原因是c++stl默认是产生max-heap,不用自己来配置。由于max-heap的顶上是最大值,所以这个问题需要转换一下:
这里写图片描述
上图,用min-heap时,由于顶上是最小值,那么我们只需要k长度的heap,先用nums的前k个数来初始化min-heap,然后对后面的n-k个数,每次插入一个,删除一个,这样留在min-heap的就是第k大以及更大的数;相反,用max-heap时,由于顶上是最大值,就从另一个角度看,我们此时需要n-k长度的heap,也用nums的前n-k个数来初始化min-heap,然后对后面的k个数,每次插入一个,删除一个,这样留在min-heap的就是第k大以及更小的数。
5.这道题,找k大的数,最快的方法还不是用heap。最优解是用quick select,可以达到on average o(n)的速度。quick select和quick sort的思想一致。下次再写!!!


//方法1:min-heap
class Solution {
private:
    struct compare{
        bool operator()(int&a,int&b){//bug:容易忽略operator()前面的bool类型!
            return a>b;     
        }
    };

public:
    int findKthLargest(vector<int>& nums, int k) {
        //
        priority_queue<int,vector<int>,compare> pq(nums.begin(),nums.begin()+k);

        for(int i=k;i<nums.size();i++){
            pq.push(nums[i]);//先push
            pq.pop();   //后pop
        }    
        return pq.top();
    }
};


//方法2:max-heap.一次成功!居然比min-heap快!
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        //
        int n=nums.size();
        priority_queue<int> pq(nums.begin(),nums.begin()+n-k+1);

        for(int i=n-k+1;i<nums.size();i++){
            pq.push(nums[i]);//先push
            pq.pop();   //后pop
        }    
        return pq.top();
    }
};

//方法3:quick select???
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        //
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值