bfprt算法,中位数的中位数算法,O(n)时间复杂度求解第k大数
发布时间:2021-01-01 16:40:08  所属栏目:大数据  来源:网络整理 
            导读: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
                
                
                
            | 
 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, Note:  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);
    }
};(编辑:宣城站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! | 

