【快速选择】Leetcode 215. 数组中的第K个最大元素
题目链接
思路
对于给定数组,求解第 \(k\) 大元素,且要求线性复杂度,正解为使用「快速选择」做法。
基本思路与「快速排序」一致,每次敲定一个基准值 \(x\),根据当前与 \(x\) 的大小关系,将范围在 \([l,r]\) 的 \(nums[i]\) 划分为到两边。
同时利用,利用题目只要求输出第\(k\) 大的值,而不需要对数组进行整体排序,我们只需要根据划分两边后,第 \(k\) 大数会落在哪一边,来决定对哪边进行递归处理即可。
代码
class Solution{
Random rand = new Random();
public int findKthLargest(int[] nums, int k){
return quickselect(nums, k, 0, nums.length - 1);
}
private int quickselect(int[] nums, int k, int left, int right){
// use random to avoid O(n^2)
int index = rand.nextInt(right - left + 1) + left;
int flag = nums[index];
nums[index] = nums[left];
int i = left, j = right;
while(i < j){
while(i < j && nums[j] <= flag){
j--;
}
nums[i] = nums[j];
while(i < j && nums[i] >= flag){
i++;
}
nums[j] = nums[i];
}
nums[i] = flag;
if(i == k - 1){
return nums[i];
}else if(i < k - 1){
return quickselect(nums, k, i + 1, right);
}else{
return quickselect(nums, k, left, i - 1);
}
}
}