zoukankan      html  css  js  c++  java
  • 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;
        }
    }
  • 相关阅读:
    TCP—为什么是AIMD?
    虚拟机是怎么实现的?
    漫谈linux文件IO
    关于大型网站技术演进的思考
    大公司里怎样开发和部署前端代码
    spawn-fcgi 代码介绍
    使用python传参form-data格式的txt请求接口
    实战scrapy抓取站长图片数据
    通过requests和lxml模块对网站数据进行爬取
    centos7.5下安装jenkins
  • 原文地址:https://www.cnblogs.com/yonezu/p/13266069.html
Copyright © 2011-2022 走看看