Leetcode 215. Kth Largest Element in an Array

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、付费专栏及课程。

余额充值