leetcode 215: the Kth Largest in array

问题描述:
给定一个整形数组array, 一个整型值k,寻找数组array中第k大的数,假定k值总有效,即0<=k<=array.length -1

算法 SELECT
输入: n个元素的数组A[1…n]和整数k, 1<=k<=n。
输出:A中的第K大元素。
1、 select(A, 1, n, k)
过程 select(A, low, high, k)
1. p = high - low + 1
2. if p < 44 then 将A排序return (A[k])
3. 令 q =⌊p/5⌋。将A分成q组,每组5个元素。如果5不整除p,则派出剩余的元素。
4. 将q组中的每一组单独排序,找出中项。所有中项的集合为M。
5. mm = select(M, 1, q, ⌈q/2⌉) {mm为中项集合的中项}
6. 将 A[low…high]分成3组
A1 = {a | a > mm}
A2 = {a | a = mm}
A3 = {a | a < mm}
7. case
|A1| ≥ k: return select(A1, 1, |A1|, k)
|A1| + |A2| ≥ k: return mm
|A1| + |A2| < k: return select(A3, 1, |A3|, k - |A1| - |A2|)
8. end case

其中阈值为44的原因这里不再讲解

以下是C++代码,为AC状态。

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        vector<int>::size_type totalCount = nums.size();
        if (totalCount < 44) {
            sort(nums.begin(), nums.end(), greater<int>());
            return nums[k - 1];
        }
        vector<int>::size_type groups = totalCount / 5;
        vector<int> mediums;
        for (vector<int>::size_type gix = 0; gix < groups; gix++) {
            sort(nums.begin() + 5 * gix, nums.begin() + 5 * (gix + 1), greater<int>());
            mediums.push_back(*(nums.begin() + 5 * gix + 2));
        }
        int mm = findKthLargest(mediums, ceil(groups / 2.0));
        vector<int> nums1, nums2, nums3;
        for (vector<int>::size_type ix = 0; ix != nums.size(); ix++) {
            if (nums[ix] > mm) {
                nums1.push_back(nums[ix]);
            }
            else if (nums[ix] < mm) {
                nums3.push_back(nums[ix]);
            }
            else {
                nums2.push_back(nums[ix]);
            }
        }
        if (nums1.size() >= k) {
            return findKthLargest(nums1, k);
        }
        else if (nums1.size() + nums2.size() >= k) {
            return mm;
        }
        else {
            return findKthLargest(nums3, k - nums1.size() - nums2.size());
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值