难度:medium
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.
思路:
一个divide-and-conquer类型的问题,具体实现上是二分搜索和快速排序的结合,去寻找第K大的数字。
首先我们可以从数组中抽出一个数,设定他为key ,一般选第一个,随机也可以:k n1 n2 n3......
然后我们保证key之前的数一定比他小,后面的一定大于等于它: n1 n2 n3...k...n123.......
之后对比这个key的位置是否处于倒数第K,如果一致,那么我们就已经找到了第K大的数字!
如果这个位置在倒数第K的左边,那说明第K大的数在key右边的那一半数字里,位置在倒数第K的右边同理。
这样,通过类似于2分搜索的方法,最终能确定第K大的数字的位置而不需要对整个数组进行排序。
(当然,也可以建立一个堆,从其顶部抽取K个数字,也能得到想要的结果)
代码:
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
k = nums.size()-k;
int begin = 0;
int end = nums.size();
while(1) {
int result = move(nums,begin,end);
if (result == k) {
return nums[result];
} else if (result < k){
begin = result+1;
} else {
end = result;
}
}
}
int move(vector<int>& nums,int b, int e) {
int i = b+1;
int j = e-1;
while(i <= j) {
while(nums[j] >= nums[b] && i <= j){
j--;
}
while (nums[i] < nums[b] && i <= j) {
i++;
}
if (i <= j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
i++;
j--;
}
}
int temp = nums[j];
nums[j] = nums[b];
nums[b] = temp;
return j;
}
};