• 215. 数组中的第K个最大元素 java解决


    题目描述:

    难度:中等
    相关标签:数组、分治、快速选择、排序、堆(优先队列)
    
    给定整数数组 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

     解决:

     思路:基于快速排序的选择方法(快速选择)

            我们知道,每次经过「划分」操作后,我们一定可以确定一个目标整数(每次默认最左边的)的最终位置 index,那么我们就在每次确定那个index后,就判断是否是符合要求的第K个最大整数的下标 p( = nums.lpength - k),

            index  = p ,直接返回那个目标整数就行

            如果不是的话,

                    当index > p 时,则向 [ l, index - 1 ] 递归继续寻找

                    而当index < p 时,则向 [ index + 1, r ] 递归继续寻找

    1. class Solution {
    2. public int findKthLargest(int[] nums, int k) {
    3. int num = quickSelect( nums, 0, nums.length - 1, k );
    4. return num;
    5. }
    6. // 快速选择
    7. public int quickSelect( int[] nums, int l, int r, int k ) {
    8. // 获取这一趟快排后确认位置的 目标整数 的下标
    9. int index = quickSort( nums, l, r );
    10. // 如果这个确认的整数的下标刚好 == k,返回即可
    11. // 如果这个确认的整数的下标 > nums.length - k,则向 [ l, index - 1 ]递归继续寻找
    12. // 如果这个确认的整数的下标 < nums.length - k,则向 [ index + 1, r ]递归继续寻找
    13. if ( index == nums.length - k ) {
    14. return nums[ index ];
    15. } else {
    16. return index > nums.length - k ? quickSelect( nums, l, index - 1, k ) : quickSelect( nums, index + 1, r, k );
    17. }
    18. }
    19. // 快排的划分
    20. public int quickSort( int[] nums, int l, int r ) {
    21. int n = nums[ l ]; // 默认每一趟快排的目标整数位最左边的整数
    22. int index = l; // 记录目标整数的下标
    23. while ( l < r ) {
    24. while( l < r ) {
    25. if ( nums[ r ] < n ) {
    26. swap(nums, l, r);
    27. index = r;
    28. break;
    29. }
    30. r --;
    31. }
    32. while ( l < r ) {
    33. if ( nums[ l ] > n ) {
    34. swap(nums, l, r);
    35. index = l;
    36. break;
    37. }
    38. l++;
    39. }
    40. }
    41. return index;
    42. }
    43. // 定义交换方法
    44. public void swap( int[] nums, int i, int j ) {
    45. int temp = nums[ i ];
    46. nums[ i ] = nums[ j ];
    47. nums[ j ] = temp;
    48. }
    49. }

    复杂度分析:时间复杂度:O(n),如上文所述,证明过程可以参考「《算法导论》9.2:期望为线性的选择算法」。
    空间复杂度:O(\log n),递归使用栈空间的空间代价的期望为 O(logn)。

     

    相似题目:(20条消息) 347. 前 K 个高频元素 java解决_其然乐衣的博客-CSDN博客

  • 相关阅读:
    微信小程序 - WXML 模板语法 - 条件渲染
    LLM - 绝对与相对位置编码 与 RoPE 旋转位置编码 源码
    (附源码)springboot美食分享系统 毕业设计 612231
    测试员如何面对30岁后的下坡路,伤不起的年龄,职业道路何去何从?
    识别一切模型RAM(Recognize Anything Model)及其前身 Tag2Text 论文解读
    第四章 使用Vitepress搭建文档网站
    Sa-Token v.1.31.0 新增拦截器 SaInterceptor 功能说明,以及旧代码迁移示例
    centos7内存过高排查
    C++常用标准算法
    8条github使用小技巧
  • 原文地址:https://blog.csdn.net/QRLYLETITBE/article/details/126953657