Description:
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.
解法一:(Accepted: beat 8%)
解题思路:
注意题目要求是找第k大的数,且array的长度可以是1!要考虑极端情况。
利用快速排序里的partition函数和二分查找。注意由于是找最大的第k个数,所以partition的时候要把数组从大到小排列,注意下面代码的判断部分。
Language: C++
class Solution {
public:
int partition(vector<int>& nums, int lo, int hi){
if(lo <hi){//考虑到数组长度为1时,lo==hi,则lo+1是不合法的
int i = lo+1, j = hi;//这里是lo+1因为下面是i--
while(i<=j){//循环执行到指针i,j重合或交叉,保证一轮partition完成
if(nums[i]<nums[lo]&&nums[j]>nums[lo])
swap(nums[i++],nums[j--]);
if(nums[i]>=nums[lo]) i++;
if(nums[j]<=nums[lo]) j--;
}
swap(nums[lo],nums[j]);//是和位置j交换,因为位置j保证它是包括他以内前子数组的最小值
return j;}
else
return 0;
}
int findKthLargest(vector<int>& nums, int k) {
int lo = 0, hi = nums.size()-1;
while(hi>lo)//这里while的作用是保证一直partition直到题目要求的位置k被正确归位。
{
int j = partition(nums,lo,hi);
if(j < k-1) lo = j+1;//注意是k-1
else if(j > k-1) hi = j-1;
else return nums[k-1];
}
return nums[k-1];//注意是k-1
}
};
Partition函数还可以这样写(findKthLargest不变):(Accepted: beat 36%)
int partition(vector<int>& a, int lo, int hi){
int i = lo, j = hi+1; int temp;
if(j>1){//考虑数组只有一个元素的情况,这个很关键
while(true){
while((a[++i]>a[lo]))
if(i == hi) break;
while((a[--j]<a[lo]))
if(j == lo) break;
if(i >= j) break;//等于也要break,即i,j相遇
swap(a[i],a[j]);
}
swap(a[lo],a[j]);//是和位置j交换,因为位置j保证它是包括他以内前子数组的最小值
return j;}
else return j-1;//数组元素为1的时候返回(hi+1)-1=hi
}
之前改这个partition函数改了很久,都是一些细节问题:
- 没考虑数组只有一个元素的情况
- 一轮partition归位结束后
a[lo]
是和a[j]
交换,不是a[i]
Happy Coding!