查找数组中第 K 大的数

这篇博客介绍了两种方法来解决寻找整数数组中第K大的元素问题。第一种方法使用位数组,遍历数组并将元素计数,通过遍历位数组找到第K个最大的元素。第二种方法基于快速选择算法,通过部分排序快速定位到第K大的元素,避免了完全排序。这两种方法都有效且适用于大数据集。
摘要由CSDN通过智能技术生成

概述

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

  • 示例 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 <= 104
    -104 <= nums[i] <= 104

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

思路一:使用位数组

遍历给定数组,将具体值存进去,然后从高位开始,遍历不为 0 的数组,直到遍历到第 K 个。

注意重复值的情况,若有重复值,需要在此处多计算几次,直到得到第 K 个

class Solution {
    public int findKthLargest(int[] nums, int k) {
        if (nums.length < k){
            return -1;
        }
        int[] a = new int[(int) Math.pow(10,5) + 1];
        for (int i = 0; i < nums.length; i++) {
            a[nums[i] + 10000]++;  // 由于存在负数,所以都移位保存
        }
        for (int i = a.length-1; i >= 0; i--) {
            if (a[i] == 0){
                continue;
            } else {
                for (int j = 0; j < a[i]; j++) { // 解决重复数字的问题
                    k = k - 1;
                    if (k == 0){
                        return i - 10000;
                    }
                }
            }
        }
        return -1;
    }
}

思路二:快速选择

基于快速排序算法,每一次排序结果,都会选择一个元素放到数组的最终位置,位置左边的数都小于该数,右边的数都大于该数。

基于这个原理,如果选择的元素,恰好是在第 K 大的位置,那么直接返回即可,不用排序完成再选择。

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

    public int quickSelect(int[] nums,int low ,int high, int index){
        if (low > high){
            return -1;
        }
        int i = low;
        int j = high;
        int baseVal = nums[i];
        while (i < j){
            while ( i < j && nums[j] >= baseVal){
                j--;
            }
            while ( i < j && nums[i] <= baseVal){
                i++;
            }
            if (i < j){
                int temp = nums[i];
                nums[i] = nums[j];
                nums[j] = temp;
            }
        }
        nums[low] = nums[i];
        nums[i] = baseVal;
        if (i == index-1){
            return nums[i];
        }else if (i > index-1){
            return quickSelect(nums,low,i-1,index);
        }else {
            return quickSelect(nums,i+1,high,index);
        }
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值