数组中的第K个最大元素

- 日理万妓 2024-04-06 11:56 206阅读 0赞

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. 1 <= k <= nums.length <= 105
  2. -104 <= nums[i] <= 104
解析:

可以改进快速排序算法来解决这个问题:在分解的过程当中,我们会对子数组进行划分,如果划分得到的 q 正好就是我们需要的下标,就直接返回 a[q];否则,如果 q比目标下标小,就递归右子区间,否则递归左子区间。这样就可以把原来递归两个区间变成只递归一个区间,提高了时间效率。这就是「快速选择」算法。

代码:
  1. public class largestK {
  2. public static void main(String[] args) {
  3. // TODO 自动生成的方法存根
  4. int [] nums = {
  5. 2,1};
  6. int k = 1;
  7. System.out.println(findKthLargest(nums,k));
  8. }
  9. public static int findKthLargest(int[] nums, int k) {
  10. k = nums.length - k;
  11. int l = 0;
  12. int h = nums.length - 1;
  13. while(l < h) {
  14. int j = partition(nums,l,h);//返回切分的位置
  15. if(j == k) {
  16. break;
  17. }else if(j < k) {
  18. //只排序所在的那一边
  19. l = j + 1;
  20. }else {
  21. h = j - 1;
  22. }
  23. }
  24. return nums[k];
  25. }
  26. public static int partition(int[] nums, int l, int h) {
  27. //切分
  28. int i = l, j = h + 1;
  29. while(true) {
  30. while(nums[++i] < nums[l] && i < h);//从左向右找到比第一个大的数
  31. while(nums[--j] > nums[l] && j > l);//从右向左找到一个比第一个小的数
  32. if(i >= j) {
  33. break;
  34. }
  35. swap(nums,i, j);
  36. }
  37. swap(nums, l, j);
  38. return j;
  39. }
  40. public static void swap(int[] a, int i, int j) {
  41. int t = a[i];
  42. a[i] = a[j];
  43. a[j] = t;
  44. }
  45. }
复杂度分析:
  • 时间复杂度:O(n)。
  • 空间复杂度:O(logn),递归使用栈空间的空间代价的期望为 O(logn)。

来源:力扣(LeetCode)
仅供学习参考!

发表评论

表情:
评论列表 (有 0 条评论,206人围观)

还没有评论,来说两句吧...

相关阅读