快速排序的左侧比当前mid小,右侧比当前mid大的特性与此题联系紧密,利用这个特定当mid为目标值时即是我们要的结果(此时虽然没有排序完,但是该数字在最终排序中的位置此时已经确定)。如果使用递归,不方便回溯,这里使用while循环,并且只管一侧的情况,减少了时间复杂度。
class Solution {
int target;
int res;
public int findKthLargest(int[] nums, int k) {
//快速排序的特点,左侧小于它,右侧大于它
target = nums.length - k;
int low = 0;
int high = nums.length - 1;
while(low < high){
int mid = partition(nums,low,high);
if(mid == target) return nums[mid];
if(mid < target) low = mid + 1; //只递归一侧
else high = mid - 1;//只递归一侧
}
return nums[low];
}
int partition(int[] arr, int low ,int high){
int i = low;
int j = high;
int x = arr[low]; //取第一个数为基准点
while(i < j){
while(i < j && arr[j] > x ){ //寻找右侧小于基准点的
j--;
}
if(i < j){
arr[i] = arr[j];
i++;
}
while(i < j && arr[i] <= x){ //寻找左侧大于基准点的
i++;
}
if(i < j){
arr[j] = arr[i];
j--;
}
}
arr[i] = x;
return i;
}
}