Find K-th largest element in an array.
Example
Example 1:
Input:
n = 1, nums = [1,3,4,2]
Output:
4
Example 2:
Input:
n = 3, nums = [9,3,2,4,8]
Output:
4
Challenge
O(n) time, O(1) extra memory.
Notice
You can swap elements in the array
思路:quick select,quick sort的变种;
找kth largest,也就是找k大的数,用pivot,把大于pivot的数,移动到左边,小于pivot的数移动到右边,
循环跳出来的时候,实际上数组被分成了三部分, start...j, j + 1, i, ....end
然后判断start + k -1 跟j的大小,来判断下一次搜索哪个空间;如果两个空间都不是,那么就是第三个空间也就是A[j+1];
因为i , j 最后错开了,中间会隔出来一个数;A[j+1];
注意:判断范围的时候,一定要是以start为起点来进行判断,start + k - 1 <= i ,k - (i - start) ,否则会出问题;
class Solution {
// quick select;
public int findKthLargest(int[] nums, int k) {
return findKth(nums, 0, nums.length - 1, k);
}
private int findKth(int[] nums, int start, int end, int k) {
int i = start; int j = end;
int mid = i + (j - i) / 2;
int pivot = nums[mid];
while(i <= j) {
while(i <= j && nums[i] > pivot) {
i++;
}
while(i <= j && nums[j] < pivot) {
j--;
}
if(i <= j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
i++;
j--;
}
}
// j, j + 1, i;
// 注意这里是start + k - 1;减一别忘记了;
if(start + k - 1 <= j) {
return findKth(nums, start, j, k);
}
if(start + k - 1 >= i) {
return findKth(nums, i, end, k - (i -start));
}
return nums[j + 1];
}
}