Leetcode 215. Kth Largest Element in an Array

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

Example 1:

Input: [3,2,1,5,6,4] and k = 2
Output: 5
Example 2:

Input: [3,2,3,1,2,4,5,5,6] and k = 4
Output: 4
Note:
You may assume k is always valid, 1 ≤ k ≤ array’s length.


方法一:Arrays.sort() 排序

class Solution {
    public int findKthLargest(int[] nums, int k) {
        Arrays.sort(nums);
        return nums[nums.length - k];
    }
}



方法二:利用Partition算法

之前写过使用Partition算法找数组中位数,同理,找第k大的数也可以用Partition算法。

由于我们的目标是找到第K大数,不需要把每一个数都排好序,因此还有优化的空间。除了排序以外,我们还可以用快排中的Partition思想。
首先,随机选取一个数作为分类的标准,比它大的都放在它左边,比它小的都放在它右边。

  • 如果这个数的下标刚好是k ,那么这个数就是第k大的数;
  • 如果这个数的下标小于k,说明第k大的数在它的右边;
  • 如果这个数的下标大于k,说明第k大的数在它的左边 ;

例如:
{3,2,1,5,6,4},从大到小排序后为{6,5,4,3,2,1},第2大的数是5。

  • 5的下标为2,说明5就是第2大的数;
  • 6的下标为1,说明第2大的数在6的右边;
  • 4的下标为3,说明第2大的数在4的左边;

这是一个典型的递归过程~

class Solution {
    public int findKthLargest(int[] nums, int k) {
        return findKthLargestByPartition(nums, 0, nums.length - 1, k - 1);
    }
    
    private static int findKthLargestByPartition(int[] nums, int left, int right, int k) {
        
        // 设置i、j为左右标志位
        int i = left, j = right; 
        
        // key为分类的标志
        int key = nums[left];
        
        while(i < j) {
            // j向左走,直到遇见一个比key大的数
            while(i < j && nums[j] <= key) {
                 j--;
            }
            // 把比key大的数,放在位置i上
            if(i < j) {
                nums[i] = nums[j];
                i++;
            }
            
            // i向右走,直到遇见一个比key小的数
            while(i < j && nums[i] >= key) {
                i++;
            }
            // 把比key小的数,放在位置j上
            if(i < j) {
                nums[j] = nums[i];
                j--;
            }
        }

        nums[i] = key;
        
        // i小于k,说明第k大的数在nums[i]的右边
        if(i < k) {
            return findKthLargestByPartition(nums, i + 1, right, k);
        }
        // i大于k,说明第k大的数在nums[i]的左边
        else if(i > k) {
            return findKthLargestByPartition(nums, left, i - 1, k);
        }
        
        // i等于k ,那么nums[i]就是第k大的数
        return nums[i];
    }
    
  
}

从时间上看,Partition耗时54ms,Arrays.sort()排序耗时4ms

在这里插入图片描述

同理,可以将Partision算法用于 “最小的k个数”
https://blog.csdn.net/u010429424/article/details/77934539

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值