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

249 阅读2分钟

这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

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

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

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:

输入: [3,2,1,5,6,4] 和 k = 2 输出: 5 示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4 输出: 4

解题思路

我们可以用快速排序来解决这个问题,先对原数组排序,再返回倒数第 k 个位置,这样平均时间复杂度是 O(nlogn),但其实我们可以做的更快。

我们先回顾一下快速排序

它的基本思想是:选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分;其中一部分的所有数据都比另外一部分的所有数据都要小。然后,再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

快速排序流程:
(1) 从数列中挑出一个基准值。
(2) 将所有比基准值小的摆放在基准前面,所有比基准值大的摆在基准的后面(相同的数可以到任一边);在这个分区退出之后,该基准就处于数列的中间位置。
(3) 递归地把"基准值前面的子数列"和"基准值后面的子数列"进行排序。

利用快速排序中的partition函数,我们可以找出一个中枢值,中枢值的左边元素均大于中枢值,中枢值的右边元素均小于中枢值,因此利用这个中枢值,我们可以每次都缩小区间,如果k是大于中枢值下标的说明我们只需要在中枢值的右边区间查找,否则就在左边区间查找

代码

class Solution {
    public int findKthLargest(int[] nums, int k) {

        int l=0,r=nums.length-1;
        k=nums.length-k;
        while (true)
        {
            int mid=partition(nums,l,r);
            if (mid==k)
                return nums[mid];
            else if (mid<k)
                l=mid+1;
            else r=mid-1;
        }



    }
    public int partition(int[] nums, int l,int r) {

        int temp=nums[l];
        while (l<r)
        {
            while (l<r&&nums[r]>=temp)
                r--;
            nums[l]=nums[r];

            while (l<r&&nums[l]<=temp)
              l++;
            nums[r]=nums[l];
        }
        nums[l]=temp;
        return l;
    }
}