加入收藏 | 设为首页 | 会员中心 | 我要投稿 威海站长网 (https://www.0631zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间:2021-01-02 13:25:49 所属栏目:大数据 来源:网络整理
导读: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 kt

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);
    }
};

(编辑:威海站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读