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) {
//
}
};