無序數組中找第k大的數


類快排算法

leetcode215

由於只要求找出第k大的數,沒必要將數組中所有值都排序。

快排中的partition算法,返回key在數組中的位置的cnt(相對於left的偏移量),如果cnt正好等於k,那么問題則得到解決;如果cnt小於k,去左邊找第k個;如果cnt>k,則去右邊找第k-cnt個。直到key的位置等於k-1,則找對問題的解。

/*快排中的划分算法*/
int partition(int* input, int low, int high)
 {
    int tmp = input[low]; // 取一個基准元素

    while (low < high) {
        while (low < high && input[high] >= tmp) {
            high--;
        }
        input[low] = input[high];

        while (low < high && input[low] <= tmp) {
            low++;
        }
        input[high] = input[low];
    }

    input[low] = tmp;
    return low;
}

// 這里得到的是第k小,自己n-k轉換下即可, 或者改下划分函數
int findK(int* array, int left, int right, int k) {
    //printf("%d %d %d\n", left, right, k);
    int i = partition(array, left, right);
    int cnt = i - left + 1;
    if (k == cnt) {
        return array[i];
    } else if (k < cnt) {
        return findK(array, left, i - 1, k);
    } else if (k > cnt) {
        return findK(array, i + 1, right, k-cnt);
    }
    return 0;
}

此解法的時間復雜度為O(N*lgK),logK次每次O(N),優於排序解法

最小堆解法

構造一個大小為k的最小堆,堆中根節點為最小值。如果數組中最大的幾個數均在堆中,那么堆中根節點的值就是問題的解。

可以用STL中的優先隊列實現,因為優先隊列的內部就是最大堆/最小堆實現的。

此解法的時間復雜度O(NlogK),N次logK。但是相比與類快速排序算法,需要額外的存儲空間。

 

 

參考鏈接:

1. https://www.jianshu.com/p/33ee33ce8699

2. https://blog.csdn.net/qq_14821023/article/details/50793468


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM