数组中第k个最大的数(TopK)三种解法

1.堆排

class Solution {
     public int findKthLargest(int[] nums, int k) {
        initHeap(nums);
        for (int i = nums.length - 1; i > nums.length - k; i--) {
            swap(nums,0,i);
            heapSort(nums,0,i);
        }
        return nums[0];
     }
     public void initHeap(int[] nums) {
         for (int i = nums.length / 2; i >= 0; i--) {
             heapSort(nums,i,nums.length);
         }
     }
     public void heapSort(int[] nums,int parent, int length) {
         int left = 2 * parent + 1;
         int right = left + 1;
         int maxIndex = parent;
         if (left < length && nums[left] > nums[maxIndex]) {
             maxIndex = left;
         }
         if (right < length && nums[right] > nums[maxIndex]) {
             maxIndex = right;
         }
         if (maxIndex != parent) {
             swap(nums,maxIndex,parent);
             heapSort(nums,maxIndex,length);
         }
     }
     public void swap(int[] nums, int x, int y) {
         int temp = nums[x];
         nums[x] = nums[y];
         nums[y] = temp;
     }
 }

2.快排+二分

 
class Solution {
     public int findKthLargest(int[] nums, int k) {
       int left = 0;
       int right = nums.length - 1;
       while (left <= right) {
           //小于等于nums[mid]的数有mid个
           int mid = fastOrder(nums,left,right);
           //大于等于nums[mid]的有nums.length - mid个,当k = nums.length -mid时,nums[mid]就是第k大个数。
           if (mid == nums.length - k) {
               return nums[mid];
           }else if (mid > nums.length - k) {
               right = mid - 1;
           }else {
               left = mid + 1;
           }
       }
       return -1;
     }
     public int fastOrder(int[] nums, int left, int right) {
         int l = left;
         int r = right;
         while (l < r) {
             while (l < r && nums[r] >= nums[left]) r--;
             while (l < r && nums[l] <= nums[left]) l++;
             swap(nums,l,r);
         }
         swap(nums,left,r);
         return l;
     }
     public void swap(int[] nums, int x, int y) {
         int temp = nums[x];
         nums[x] = nums[y];
         nums[y] = temp;
     }
 }

3.纯二分

class Solution {
     public int findKthLargest(int[] nums, int k) {
         //数组中最大值
        int high = Integer.MIN_VALUE;
         //数组中最小值
        int low = Integer.MAX_VALUE;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] > high) high = nums[i];
            if (nums[i] < low) low = nums[i];
        }
        //low 与high中元素个数
        int count = 0;
 ​
        while (low <= high) {
            int mid = low + (high - low) / 2;
            count = betweenCount(nums,mid,high);
            if (count > k) {
                low = mid + 1;
            }else if (count < k) {
                high = mid - 1;
                k = k - count;
            }else {
                return minCount(nums,mid);
            }
        }
        return high;
     }
     //nums数组中大于等于mid的有k个,找出最小的那个,就是第k大的元素
     public int minCount(int[] nums, int mid) {
         int compare = Integer.MAX_VALUE;
         for (int i = 0; i < nums.length; i++) {
             if (nums[i] >= mid && nums[i] < compare) {
                 compare = nums[i];
             }
         }
         return compare;
     }
     //nums中大于等于start,且小于等于end的元素个数。
     public int betweenCount(int[] nums, int start,int end) {
         int count = 0;
         for (int i = 0; i < nums.length; i++) {
             if (nums[i] >= start && nums[i] <= end) {
                 count++;
             }
         }
         return count;
     }
 }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值