日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

线性时间选择(TOP K)

發布時間:2023/12/9 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线性时间选择(TOP K) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

問題描述:

找出一個數組中第K小的元素,時間復雜度為O(n)。

解法:

1.首先大家都會想到的解法是排序,之后找出第k個元素,但是排序的時間復雜度不符合要求,或者需要額外的空間。

2.利用快排的思想,以樞紐(隨機得到)為界,將數組分為2部分,一部分小于等于這個樞紐值,一部分大于這個樞紐值,與快排不同的是,我們只處理一部分,另一部分舍棄。

代碼如下:

#include<iostream> #include<algorithm> #include<time.h> #include<cstring> #define random(x) (rand()%x) //生成隨機數用的 using namespace std; //交換兩個數的值 void swap(int arr[], int i, int j) {int tem;tem = arr[i];arr[i] = arr[j];arr[j] = tem; } int partition(int arr[], int L, int R) {int less = L - 1;int more = R;while (L < more) {if (arr[L] < arr[R]) {swap(arr, ++less, L++);}else if (arr[L] > arr[R]) {swap(arr, --more, L);}else {L++;}}swap(arr, more, R); //將樞紐從最后的位置移動到分界處int p = more;return p; //返回樞紐的位置 } int quicksort_select(int arr[], int L, int R,int k) {srand((int)time(0)); //種子,為了每次生成的隨機數不同if (k > (R - L + 1) || k < 1) {return -1;}int P;if (L < R) {swap(arr, L + (int)(random(1000) / (float)(1000)*(R - L + 1)), R); //生成一個隨機數,再把隨機數所在位置的數與數組最后一個數交換P = partition(arr, L, R);}int j = P - L + 1;if (j == k) {return arr[P];}else if (j>k) {quicksort_select(arr, L, P, k);}else {quicksort_select(arr, P + 1, R, k - j);} } int main() {//textint a[5] = { 1,2,3,4,5 };int m=quicksort_select(a, 0, 4, 2);cout << m; }

代碼分析如下:

partition函數返回樞紐的坐標P,P-L+1是左半部分元素的個數,這部分的元素都小于等于樞紐的值,右半部分的元素值都大于樞紐的值,如果j<P-L+1說明第j個小的元素,在左半部分,讓后只需要遞歸的處理左半部分即可,如果P等于j,那么很幸運,樞紐的值就是我們的所求,如果j>P-L+1,說明第k個小的元素在右半部分,指的注意的是,我們所求的數是右半部分第j-(P-L+1)小的數,我們這時候處理右半部分即可。這種方法在平均的時間復雜度是O(n)(證明看《算法導論》),但他有一個額外的產生隨機數,這個的效率據說很低(沒有親自探測);

3.采用中位數線性時間選擇,我放到下一篇文章。





總結

以上是生活随笔為你收集整理的线性时间选择(TOP K)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。