LeetCode215-数组中的第k个最大元素

145 阅读1分钟

LeetCode215-数组中的第k个最大元素

1、题目

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

2、思路

拿[4,5,7,3,2,1,6,8]举例,找到第6大的元素

2.1、快排

这道题第一时间想到的就是先排序,然后拿第k个值即可。但是前文我们学了快速排序的算法,快速排序在分解数组过程中,会去划分基准元素,如果划分基准元素的索引正好是要找的第k个最大元素的索引(注意是比较索引),我们直接返回即可,不用再接着排序,也就是在排序中找到元素,这样效率会更高。

public  int findKthLargest(int[] nums,int k) {
      //第k大元素在数组中的索引就是nums.length - k
        k = nums.length - k;
        int left = 0,right = nums.length - 1;
        while (left <= right){
            //基准元素的索引,就是代表着这个元素在数组中的排好序的索引
            int p = patition(nums, left, right);
            if(p > k){
                right = p - 1;
            }else if(p < k){
                left = p + 1;
            }else {
                return nums[k];
            }
        }
        return -1;
  }

这块采用二分法缩小范围查找,对patition函数不清楚去之前发布的文章了解下快速排序

2.1、堆排

之前也学了堆排,构建堆结构之后,堆顶就是最大元素,那可以不可以在交换堆顶和堆底元素时候,交换k次,是不是就是我们想要的数?那就简单了~~

public int findKthLargest(int[] nums,int k){
        if(nums.length==1) return nums[0];
        //构建大顶堆
        buildMaxHeap(nums);
        int res = 0;
        //交换排序
        for (int i = nums.length -1 ; i >= 0; i--) {
            //先拿元素再交换下沉
            k--;
            if(k == 0){
              res = nums[0];
              break;
            }
            swap(nums,0,i);
            sink(nums,0,i - 1);
            
        }
        return res;
    }

对堆排序不明白的参考前文堆排序