要求:返回第k大的数,注意不算去重
思路:
法一:sort排序后返回,时间O(nlogn),空间O(logn)
法二:利用快排的partition函数,partition能找到一个数在数组中的位置,故只要多次调用partition找位置是len-k的即可。这里partition以首位为pivot,采用双指针交换写法。时间好的话O(n),坏的话O(n^2),空间O(1)
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
k=nums.size()-k;
int index=0,start=0,end=nums.size()-1;
while(true){
index=partion(nums,start,end);
if(index==k)return nums[index];
else if(index<k)
start=index+1;
else end=index-1;
}
return nums[index];
}
int partion(vector<int>& nums, int start, int end){
int i=start;
int j=end;
int pivot=nums[start];
while(i<j){
while(i<j&&nums[j]>=pivot)
j--;
while(i<j&&nums[i]<=pivot)
i++;
swap(nums[i],nums[j]);
}
swap(nums[start],nums[i]);
return i;
}
};
法三:大顶堆,逐步取出k个元素,时间O(nlogn),空间O(n)
法四:小根堆,取出n-k个小的,建堆时间O(klogk),取出时间O(n-k)(logk),最优,空间O(k)
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int,vector<int>,greater<int>> minheap;
for(int i=0;i<k;i++)
minheap.push(nums[i]);
int n=nums.size();
for (int i = k; i < n; ++i) {
if (nums[i] > minheap.top()) {//会被弹出去
minheap.pop();
minheap.push(nums[i]);
}
}
return minheap.top();
}
};