215. 数组中的第K个最大元素
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。
示例 1:
输入: [3,2,1,5,6,4], k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6], k = 4
输出: 4
提示:
1 <= k <= nums.length <= 105
-104 <= nums[i] <= 104
解析:
可以改进快速排序算法来解决这个问题:在分解的过程当中,我们会对子数组进行划分,如果划分得到的 q 正好就是我们需要的下标,就直接返回 a[q];否则,如果 q比目标下标小,就递归右子区间,否则递归左子区间。这样就可以把原来递归两个区间变成只递归一个区间,提高了时间效率。这就是「快速选择」算法。
代码:
public class largestK {
public static void main(String[] args) {
// TODO 自动生成的方法存根
int [] nums = {2,1};
int k = 1;
System.out.println(findKthLargest(nums,k));
}
public static int findKthLargest(int[] nums, int k) {
k = nums.length - k;
int l = 0;
int h = nums.length - 1;
while(l < h) {
int j = partition(nums,l,h);//返回切分的位置
if(j == k) {
break;
}else if(j < k) {//只排序所在的那一边
l = j + 1;
}else {
h = j - 1;
}
}
return nums[k];
}
public static int partition(int[] nums, int l, int h) {//切分
int i = l, j = h + 1;
while(true) {
while(nums[++i] < nums[l] && i < h);//从左向右找到比第一个大的数
while(nums[--j] > nums[l] && j > l);//从右向左找到一个比第一个小的数
if(i >= j) {
break;
}
swap(nums,i, j);
}
swap(nums, l, j);
return j;
}
public static void swap(int[] a, int i, int j) {
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
复杂度分析:
- 时间复杂度:O(n)。
- 空间复杂度:O(logn),递归使用栈空间的空间代价的期望为 O(logn)。
来源:力扣(LeetCode)
仅供学习参考!