题意,求数组中的第K大的数。
思路1:利用快速排序的思路,找到一个下标为n-K的下标index,前面从下标0至n-K-1的数均小于index,该下标的值即为第K大的数字
思路2:利用堆或者红黑树来解答。维护一个容量为K的容器,建立一个小根堆,遍历数组一遍,如果遍历的元素的值比堆顶元素值要大,则移除堆顶的元素,插入遍历的元素。最后得到的堆顶元素即为所求的第K大的元素。 由于multiset是基于红黑树实现的,故可以直接拿来使用
思路1的代码:
class Solution {
public:
int partition(vector<int>& nums,int l,int r)
{
int i=l,j=r;
int tmp =nums[i];
while(i<j)
{
while(i<j&&nums[j]>=tmp)
j--;
if(i<j)
nums[i++]=nums[j];
while(i<j&&nums[i]<tmp)
i++;
if(i<j)
nums[j--]=nums[i];
}
nums[i]=tmp;
return i;
}
int findKthLargest(vector<int>& nums, int k)
{
int size = nums.size();
int l =0,r=size-1;
int index=partition(nums,0,size-1);
while(index!=size-k){
if(index>size-k){
index = partition(nums,l,index-1);
}
else{
index = partition(nums,index+1,r);
}
}
return nums[index];
}
};
//此处为学习函数对象的使用,实际上multiset 默认是升序排列的。
template<class T>
class less_{
public:
bool operator()(const T& x,const T& y)const{
return x<y;
}
};
class Solution {
public:
multiset<int,less_<int>> mset; //可以写作 multiset<int> mset;
typedef multiset<int>::iterator iter;
int findKthLargest(vector<int>& nums, int k) {
if(k<1||nums.size()<k)
return 0;
int size=nums.size();
vector<int>::iterator it = nums.begin();
for(;it!=nums.end();++it)
{
if(mset.size()<k)
mset.insert(*it);
else{
iter it_mset = mset.begin();
if(*it>*it_mset){
mset.erase(it_mset);
mset.insert(*it);
}
}
}
return *(mset.begin());
}
};