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 l, int r, 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;i5, 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,l,r, pos);

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

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

你可能感兴趣的:(#,数学-组合)