第k大数或第k小的数的O(n)解法

  前置算法:快速排序

 

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

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

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

  一个普通的思路是从大到小排序后直接取第k个元素,时间复杂度是$O(nlogn)$。

  要达到平均$O(n)$的复杂度,可以借助快速排序的想法,对于一个区间内的数,任意取一个数x,将比它大的放在左边,比它小的放在右边,结束后查看x是第几个元素。如果x的序数为k,x就是答案;不是,继续取更小的区间。

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        k--;
        int left=0,right=nums.size()-1;
        while (true){
            int l=left,r=right,key=nums[l];
            while (l<r){
                while (l<r&&key>=nums[r])
                    r--;
                nums[l]=nums[r];
                while (l<r&&nums[l]>=key)
                    l++;
                nums[r]=nums[l];
            }
            nums[l]=key;
            if (l==k)
                return key;
            else if (k<l)
                right=l-1;
            else
                left=l+1;
        }
    }
};

 

posted @ 2022-06-15 22:44  wegret  阅读(169)  评论(0)    收藏  举报