1. 程式人生 > 實用技巧 >快速選擇演算法

快速選擇演算法

快速選擇演算法

快速選擇演算法基於快速排序演算法,時間複雜度由\(O(nlogn)\)降到\(O(n)\)

思想是這樣的,快速選擇不需要所有的資料,只需要知道這個數排在第幾位

而快速排序演算法剛好可以滿足這個要求,因為快速選擇演算法每次都將整個區間一分為二,每次對比可以知道要求的數在哪個區間,然後選擇對應的區間進行遞迴即可。

時間複雜度之所以降低,就是因為快速選擇演算法不需要遞迴兩邊。

#include <iostream>
using namespace std;
const int maxn = 1e5 + 10;
int q[maxn], n, m;

int solve(int l, int r, int k)
{
    if (l == r)
        return q[l];//保證了k一直在[l,r]中,區間裡只有一個數的時候說明找到了答案
    int tmp = q[l + r >> 1];
    int i = l - 1, j = r + 1;
    while (i < j) {
        while (q[++i] < tmp);
        while (q[--j] > tmp);
        if (i < j)
            swap(q[i], q[j]);
    }
    int sl = j - l + 1;//求出區間的長度,之所以用j,是因為這個是由下面如何遞迴決定的。遞迴的是solve(l,j,k),說明區間長度就是j-l+1。如果換成i,就必須用遞迴區間為i的方式
    if (k <= sl)
        return solve(l, j, k);
    else
        return solve(j + 1, r, k - sl);
}

int main()
{
    cin >> n >> m;
    for (int i = 0; i < n; i++)
        cin >> q[i];
    cout << solve(0, n - 1, m);
    return 0;
}