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 ] 递归继续寻找

class Solution {

    public  int findKthLargest(int[] nums, int k) {
        int num = quickSelect( nums, 0, nums.length - 1, k );
        return num;
    }

    // 快速选择
    public int quickSelect( int[] nums, int l, int r, int k ) {
        
        // 获取这一趟快排后确认位置的 目标整数 的下标
        int index = quickSort( nums, l, r );

        // 如果这个确认的整数的下标刚好 == k,返回即可
        // 如果这个确认的整数的下标 > nums.length - k,则向 [ l, index - 1 ]递归继续寻找
        // 如果这个确认的整数的下标 < nums.length - k,则向 [ index + 1, r ]递归继续寻找 
        if ( index == nums.length - k ) {
            return  nums[ index ];
        } else {
            return index > nums.length - k ? quickSelect( nums, l, index - 1, k ) : quickSelect( nums, index + 1, r, k );
        }
    }

    // 快排的划分
    public int quickSort( int[] nums, int l, int r ) {
        int n = nums[ l ];  // 默认每一趟快排的目标整数位最左边的整数
        int index = l;      // 记录目标整数的下标
        while ( l < r ) {
            while( l < r ) {
                if ( nums[ r ] < n ) {
                    swap(nums, l, r);
                    index = r;
                    break;
                }
                r --;
            }
            while ( l < r ) {
                if ( nums[ l ] > n  ) {
                    swap(nums, l, r);
                    index = l;
                    break;
                }
                l++;
            }
        }
        return index;
    }


    // 定义交换方法
    public void swap( int[] nums, int i, int j ) {
        int temp = nums[ i ];
        nums[ i ] = nums[ j ];
        nums[ j ] = temp;
    }


}

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

 

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值