微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

bfprt算法,中位数的中位数算法,O(n)时间复杂度求解第k大数

215. Kth Largest Element in an Array

题目地址

https://leetcode.com/problems/kth-largest-element-in-an-array/

题目描述

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order,not the kth distinct element.

For example,
Given [3,2,1,5,6,4] and k = 2,return 5.

Note:
You may assume k is always valid,1 ≤ k ≤ array’s length.

bfprt 求解,ac代码如下

class Solution {
public:

    /* 快排思路 一次划分 */
    int quickpart(vector<int> &a,int l,int r,int pos)
    {
        int tmp = a[pos];
        a[pos] = a[l];
        a[l] = tmp;

        int pivot = a[l];
        int i = l;  
        int j = r;  
        while(i < j)  
        {  
            while(a[j] >= pivot && i < j)  
                j--;  
            a[i] = a[j];  
            while(a[i] < pivot && i < j)  
                i++;  
            a[j] = a[i];  
        }  
        a[i] = pivot;  
        return i;  
    }

    /* bfprt 算法*/
    int bfprt(vector<int> &a,int k)
    {
        if(r - l + 1 <= 5) // 小于等于5个元素 直接排序输出结果
        {
            sort(a.begin()+l,a.begin() + r + 1);
            return a[l + k - 1];
        }

        // 1 首先把数组按5个数为一组进行分组,最后不足5个的忽略。对每组数进行排序(如插入排序)求取其中位数。
        // 2 把上一步的所有中位数移到数组的前面
        int t = l;
        int cnt = (r - l + 1) / 5;
        for(int i=0;i<cnt;i++)
        {
            sort(a.begin() + l + i*5,a.begin() + l + (i+1) *5);

            int tmp = a[l + i * 5 + 2];
            a[l + i * 5 + 2] = a[t];
            a[t] = tmp;

            t++;
        }
        t--;

        // 3 对这些中位数递归调用BFPRT算法求得他们的中位数
        int pos = (l + t) / 2; // l-t的中位数的下标, 中位数是第 pos - l + 1数
        bfprt(a,l,t,pos - l + 1); // 递归查找中位数的中位数,确保中位数在pos这个位置

        // 4 将上一步得到的中位数作为划分的主元进行整个数组的划分,快排思路
        int m = quickpart(a,r,pos);

        // 5 判断第k个数在划分结果的左边、右边还是恰好是划分结果本身,前两者递归处理,后者直接返回答案。
        if(m - l +1 == k)
            return a[m];
        else if(m-l + 1 < k)
            return bfprt(a,m+1,k - (m-l+1));
        else 
            return bfprt(a,m -1,k);;
    }

    int findKthLargest(vector<int>& nums,int k) {
        int len = nums.size();
        return bfprt(nums,0,len-1,len-k+1);
    }
};

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐