kth Largest Element

题目:

Find K-th largest element in an array.

Example: In array [9,3,2,4,8], the 3rd largest element is 4.

In array [1,2,3,4,5], the 1st largest element is 5, 2nd largest element is 4, 3rd largest element is 3 and etc.

分析:

这道题有几种方法可以做

算法提高班内容,分析起来比较有意思,同时也参看九章的答案。
(1) 用O(nlogn)排序,返回第K个元素
(2) 用minHeap做O(n)的算法,但是空间复杂度是O(k)
(3) 用QuickSort思想做O(n)的算法,但是空间复杂度是O(1)

除此之外 在这个博客里面说了7种方法 http://www.cnblogs.com/zhjp11/archive/2010/02/26/1674227.html

1 我们可以对这个乱序数组按照从大到小先行排序,然后取出前k大,总的时间复杂度为O(n*logn + k)。
2 利用选择排序或交互排序,K次选择后即可得到第k大的数。总的时间复杂度为O(n*k)
3 利用快速排序的思想,从数组S中随机找出一个元素X,把数组分为两部分Sa和Sb。Sa中的元素大于等于X,Sb中元素小于X。这时有两种情况:
3.1 Sa中元素的个数小于k,则Sb中的第k-|Sa|个元素即为第k大数;
3.2 Sa中元素的个数大于等于k,则返回Sa中的第k大数。时间复杂度近似为O(n)
4 二分[Smin,Smax]查找结果X,统计X在数组中出现,且整个数组中比X大的数目为k-1的数即为第k大数。时间复杂度平均情况为O(n*logn)
5 用O(4*n)的方法对原数组建最大堆,然后pop出k次即可。时间复杂度为O(4*n + k*logn)
6 维护一个k大小的最小堆,对于数组中的每一个元素判断与堆顶的大小,若堆顶较大,则不管,否则,弹出堆顶,将当前值插入到堆中。时间复杂度O(n * logk)
7 利用hash保存数组中元素Si出现的次数,利用计数排序的思想,线性从大到小扫描过程中,前面有k-1个数则为第k大数,平均情况下时间复杂度O(n)

解法1:QuickSort

class Solution {
public:
    /*
     * param k : description of k
     * param nums : description of array and index 0 ~ n-1
     * return: description of return
     */
    int kthHelper(vector<int> nums, int left, int right, int k) {
        if (left == right) {
            return nums[left];
        }
        int i = left;
        int j = right;
        int pivot = nums[i + (j - i) / 2];
        while (i <= j) {
            while (i <= j && nums[i] < pivot) {
                i++;
            }
            while (i <= j && nums[j] > pivot) {
                j--;
            }
            if (i <= j) {
                swap(nums[i], nums[j]);
                i++;
                j--;
            }
        }

        if (left + k - 1 <= j) {
            return kthHelper(nums, left, j, k);
        }
        if (left + k - 1 < i) {
            return nums[left + k - 1];
        }
        return kthHelper(nums, i, right, k - (i - left));
    } 

    int kthLargestElement(int k, vector<int> nums) {
        // write your code here
        return kthHelper(nums, 0, nums.size() - 1, nums.size() - k + 1);
    }
};

解法2:minHeap

class Compare {
public:
    bool operator() (int lhs, int rhs) {
        return lhs > rhs;
    }
};

class Solution {
public:
    /*
     * param k : description of k
     * param nums : description of array and index 0 ~ n-1
     * return: description of return
     */
    int kthLargestElement(int k, vector<int> nums) {
        // write your code here
        if (nums.size() < k) {
            return -1;
        }
        priority_queue<int, vector<int>, Compare> mH;
        for (int i = 0; i < nums.size(); i++) {
            if (mH.size() < k) {
                mH.push(nums[i]);
            } else {
                int temp = mH.top();
                if (nums[i] > temp) {
                    mH.pop();
                    mH.push(nums[i]);
                }
            }
        }
        return mH.top();
    }
};

results matching ""

    No results matching ""