算法小知识-----8.10-----数组中的第K个最大元素

90 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第13天,点击查看活动详情

数组中的第K个最大元素

该题出自力扣的215题 —— 数组中的第K个最大元素【中等题】

审题

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

  • 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
  • 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。
  • 题意很简单,就是要找出一个数组内第K个最大的元素,也很直接明了。
  • 首当其冲的就是排序了,只要对数组排序后,便可以用数组的随便访问 直接找到对应的元素
    • 虽然说复杂度O(n)的算法解决问题,但是直接调用内部库,也是比较小聪明的方法
    • 直接Arrays.sort排序之后返回数组对应的下标
  • 剖析该题会发现,就是很明确的排序题
    • 冒泡是双重for循环,复杂度O(n²),就算是剪枝后也无法直接打到n
    • 可以尝试使用快排去解决该题
      • 找出基准数,把数组大于基准数和小于基准数,划分成两个子数组
      • 递归使用两个子数组,不断划分,最终返回完整数组

编码

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

image.png

class Solution {
    // public int findKthLargest(int[] nums, int k) {
    //     Arrays.sort(nums);
    //     int len = nums.length;
    //     return nums[len -k];
    // }
        public int findKthLargest(int[] nums, int k) {
        quickSort1(nums,0,nums.length -1);
        return nums[nums.length - k];
    }
       private void quickSort1(int[] arr, int left, int right) {
        // 递归结束的条件
        if(right < left){
            return;
        }

        int left0 = left;
        int right0 = right;

        //计算出基准数
        int baseNumber = arr[left0];

        while(left != right){
//        1,从右开始找比基准数小的
            while(arr[right] >= baseNumber && right > left){
                right--;
            }
//        2,从左开始找比基准数大的
            while(arr[left] <= baseNumber && right > left){
                left++;
            }
//        3,交换两个值的位置
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
        }
        //基准数归位
        int temp = arr[left];
        arr[left] = arr[left0];
        arr[left0] = temp;

        // 递归调用自己,将左半部分排好序
        quickSort1(arr,left0,left-1);
        // 递归调用自己,将右半部分排好序
        quickSort1(arr,left +1,right0);

    }

}

image.png