1. 程式人生 > >無序陣列中第K大的數

無序陣列中第K大的數

1. 排序法

時間複雜度 O(nlogn)

2. 使用一個大小為K的陣列arr儲存前K個最大的元素

遍歷原陣列,遇到大於arr最小值的元素時候,使用插入排序方法,插入這個元素

時間複雜度,遍歷是 O(n), 插入 O(K), 所以時間複雜度 O(nK)

3. 二叉堆--小頂堆

維護一個有K個元素的小頂堆,堆頂就是最小值。

遍歷剩餘 n-K 個元素,大於堆頂就插入堆並調整。

時間複雜度是遍歷 O(n-K), 調整堆 O(K), 所以時間複雜度 O( (n-K)log(K) )

4. 分治法

類似快速排序,找到一個key,把陣列中大於key的放在前面,小於key的放在後面

如果key的下標正是要找的K,結束。否則,K小於key下標的話,遞迴處理前半部分,否則,遞迴處理後半部分

時間複雜度是 o(n)

#include <iostream>
#include <cstring>

using namespace std;


int func(int *arr, int l, int r, int k)
{
    if (k-1 < l || k-1 > r)
    {
        return -1;
    }

    int p = l;
    int key = arr[r];
    for (int
i = l; i < r; ++i) { if (arr[i] > key) { int tmp = arr[p]; arr[p] = arr[i]; arr[i] = tmp; p++; } } if (p == k-1) { return key; } else if (p > k-1) { return func(arr, l, p-1, k); }
else { arr[r] = arr[p]; return func(arr, p+1, r, k); } } int main() { int arr[] = {12,43,56,7,90,7,0,8,58,32,21}; int len = sizeof(arr) / sizeof(int); int *tmp = new int[len]; for (int i = -1; i <= len+1; ++i) { memcpy(tmp, arr, sizeof(arr)); cout << func(tmp, 0, len-1, i) << ' '; } delete[] tmp; return 0; }