//用快速排序来写的 这里一定要明确每个变量的定义,不然很容易出错
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
return findKthLargest(nums, 0, nums.size() - 1, k);
}
//在[l,r]之间寻找第k大个元素
private:
int findKthLargest( vector<int>& nums, int l, int r, int k ){
//递归到底的情况
if( l > r) return -1;
int MinIndex = nums.size() - k ;// 这里求的是第k大的元素对应的数组下标
int n = partition( nums, l, r);
if( n > MinIndex )
return findKthLargest(nums, 0, n-1, k);
else if( n < MinIndex)
return findKthLargest(nums, n+1, nums.size()-1, k);
else
return nums[n];
}
//返回p使得 [0,p]都小于/等于nums[0], (p,r] 都大于nums[0]
int partition( vector<int>& nums, int l, int r){
//(l,j]中保存小于/等于的, (j,i)中保存大于的
int j = l;
for( int i = j + 1; i <= r; i++){
if( nums[i] < nums[l] ){
swap( nums[i], nums[++j] );
}
}
swap( nums[l], nums[j] ); //最后这一步交换不要忘记了
return j;
}
};
(虽然用时高的离谱。。。)
注意事项
1 快速排序是一个递归的算法,一定要有一个递归到底的判断 即上面的 if( l > r) return -1;
2 快速排序是一个递归的算法,所以
if( n > MinIndex )
return findKthLargest(nums, 0, n-1, k);
这里的 return
不能忘记,如果不return的话这一步的值就没法带回去
并且在partition中,由于是递归的算法,数组的下标就并不都是从0开始的了,所以在交换的时候,不能用swap( nums[0], nums[ l ] );
,要先用 j将原来的第一个元素l保存起来,然后用swap( nums[ l ], nums[j] );
3 k的值并不随着递归的变化而变化,因为每次只是截取数组的一小部分来看,此时数组的下标没变,k在新数组中的下标也是没有变化的
4 一定要明确好变量的定义,这样写的时候才不会写错!