随机选择算法
题目链接
https://leetcode.cn/problems/kth-largest-element-in-an-array/
无序数组中寻找第 K 大的数
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题
思路分析
沿用了随机快排的思路,随机一个数,划分区间,判断传进来的 i 在哪个区间,然后递归调用
区别于随机快排,随机选择排序对不符合要求的区间无需排序
代码实现
java
class Solution {
// 表示边界
public static int first;
public static int last;
public int findKthLargest(int[] nums, int k) {
return randomizeSelect(nums, nums.length - k);
}
// 返回的是数组排好序后,i 位置的值
public int randomizeSelect(int[] arr, int i) {
int ans = 0;
for (int l = 0, r = arr.length - 1; l <= r;) {
int x = arr[l + (int) (Math.random() * (r - l + 1))];
partition(arr, l, x, r);
if (i < first){
r = first - 1;
} else if (i > last) {
l = last + 1;
} else {
ans = arr[i];
break;
}
}
return ans;
}
public void partition(int[] arr, int l, int x, int r) {
first = l;
last = r;
int i = l;
while (i <= last) {
if (arr[i] == x) {
i++;
} else if (arr[i] < x) {
swap(arr, i, first);
first++;
i++;
} else {
swap(arr, i, last);
last--;
}
}
}
public void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}复杂度分析
(1)时间复杂度 O(n)
(2)额外空间复杂度 O(1)
除了用原数组,都是有限级的变量,递归都没用,判断范围,去哪个区间找
