問題描述:
找出乙個陣列中第k小的元素,時間複雜度為o(n)。
解法:1.首先大家都會想到的解法是排序,之後找出第k個元素,但是排序的時間複雜度不符合要求,或者需要額外的空間。
2.利用快排的思想,以樞紐(隨機得到)為界,將陣列分為2部分,一部分小於等於這個樞紐值,一部分大於這個樞紐值,與快排不同的是,我們只處理一部分,另一部分捨棄。
**如下:
#include#include#include#include#define random(x) (rand()%x) //生成隨機數用的
using namespace std;
//交換兩個數的值
void swap(int arr, int i, int j)
int partition(int arr, int l, int r)
else if (arr[l] > arr[r])
else
} swap(arr, more, r); //將樞紐從最後的位置移動到分界處
int p = more;
return p; //返回樞紐的位置
}int quicksort_select(int arr, int l, int r,int k)
int p;
if (l < r)
int j = p - l + 1;
if (j == k)
else if (j>k)
else
}int main() ;
int m=quicksort_select(a, 0, 4, 2);
cout << m;
}
**分析如下:
partition函式返回樞紐的座標p,p-l+1是左半部分元素的個數,這部分的元素都小於等於樞紐的值,右半部分的元素值都大於樞紐的值,如果jp-l+1,說明第k個小的元素在右半部分,指的注意的是,我們所求的數是右半部分第j-(p-l+1)小的數,我們這時候處理右半部分即可。這種方法在平均的時間複雜度是o(n)(證明看《演算法導論》),但他有乙個額外的產生隨機數,這個的效率據說很低(沒有親自探測);
TopK問題 線性時間選擇
相信計算機專業的同學應該都對快速排序有或多或少的了解。設定此模組是因為,線性時間選擇topk與快速排序的思想有相通之處,可以輔助我們理解。快速排序的思路 設定乙個瞭望元素 劃分元素 以此元素為基礎,將工作區間 l,r 內的所有元素分割成兩部分。劃分元素以左均比其小,劃分元素以右均比其大。對分割元素左...
Top k問題(線性時間選擇演算法)
問題描述 給定n個整數,求其中第k小的數。分析 顯然,對所有的資料進行排序,即很容易找到第k小的數。但是排序的時間複雜度較高,很難達到線性時間,雜湊排序可以實現,但是需要另外的輔助空間。演算法 linearselect s,k 輸入 陣列s 1 n 和正整數k,其中1 k n 輸出 s中第k小的元素...
線性時間選擇
今天學習了線性時間選擇,主要是通過快排的方法,在乙個平均時間線性的情況下進行第k小元素的選擇,結合一道題目進行描述 題目來自演算法設計與分析就是王曉東的那本 output.txt 這題目分析一下可以得出就是尋找中位數 為什麼呢?將這些數字排列在數軸上尋找乙個到各個點距離最小的那個點,可以得知最中間的...