215. 数组中的第K个最大元素

两种复杂度O(n)的方法

方法一:快速选择

class Solution {
    public int findKthLargest(int[] nums, int k) {
        int lo = 0, hi = nums.length - 1;   // 当前partition 函数的区间边界
        int target = nums.length - k;       // 第 K 大的元素应该在什么位置
        int cur = -1;                       // 存放partition函数的返回值
        
        while(cur != target){               // 只要还没找到这个第 k 大
            cur = partition(lo, hi, nums);
            if(cur < target){
                lo = cur + 1;           // 往右找
            }else if(cur > target){
                hi = cur - 1;           // 往左找
            }
        }
        
        return nums[cur];
    }
    public void swap(int i, int j, int[] nums){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
    public int partition(int lo, int hi, int[] nums){
        if(lo == hi) return lo;     // 区间中只有一个元素,直接返回元素的索引
        
        // 从区间中随机选个数 n,并将它先挪到整个区间最右边
        int randIdx = lo + (int)(Math.random() * (hi - lo + 1));
        int n = nums[randIdx];
        swap(randIdx, hi, nums);
        
        // 利用双指针对整个区间进行分区
        int l = lo, r = hi - 1;
        while(l < r){
            while(l < r && nums[l] <= n) l ++;
            while(l < r && nums[r] > n) r --;   
            swap(l, r, nums);
        }
        
        // 分区完成后再将 n 移动到正确的位置
        if(nums[l] > n){
            swap(l, hi, nums);
            return l;
        }
        return hi;
    }
}

方法二 计数排序

class Solution {
    //采用计数排序
    public int findKthLargest(int[] nums, int k) {
        if(nums==null || nums.length==0) return -1;
        int max=nums[0];
        int min=nums[0];
        for (int i = 1; i < nums.length; i++) {
            max = Math.max(max, nums[i]);
            min = Math.min(min, nums[i]);
        }
        int[] output = new int[max-min+1];
        for (int i = 0; i < nums.length; i++) {
            output[nums[i]-min]++;
        }
        int count = 0;
        for (int i = output.length-1; i >= 0; i--) {
            count+=output[i];
            if(count>=k) {
                return i+min;
            }
        }
        return -1;
    }
}
原文地址:https://www.cnblogs.com/yonezu/p/13266069.html