2個有序陣列求合併後的中位數
阿新 • • 發佈:2019-02-19
原題:2個等長,有序陣列x[], y[],求2個數組合並後的中位數。
這裡有一個問題:2個長度為n的陣列,合併後長度為2n,那麼這個中位數是第n個呢,還是第n+1個呢?這點我也沒想明白,就按第n個算。
這個問題的實質,就是求合併後長度為2n的陣列中的第n個數。
方法一:合併2個有序陣列,比較次數是n+n. 其實我們沒必要完全排序這2個數組,只要排序前n個即可,只要的話比較次數剛好為n;
程式碼如下:
#include<iostream> using namespace std; int find(int *a,int *b,int len) { int i = 0,j = 0;//分別指向a,b陣列的當前元素 int count = 1;//因為i=j=0,已經開始計數第一個元素了 //下一步無論哪一個++,都計數的是第二個元素,所以這裡count從開始計數 while(count<len) { if(*(a+i)<=*(b+j)) { i++; }else { j++; } count++; } return *(a+i); } int main() { int a[] = {1,3,5,7,9}; int b[] = {12,14,16,18,114}; int len = sizeof(a)/sizeof(a[0]); int result = find(a,b,len); cout<<result<<endl; getchar(); return 0; }
方法二:二分法思想,複雜度應該是O(lgn)
首先比較陣列x,y的中間元素 x[n/2], y[n/2],
a. 如果x[n/2] == y[n/2],那麼說明x[mid]就是第n大的數,也就是那個中位數。
b. 如果x[n/2] > y[n/2],那麼說明y[0] - y[n/2]之間的n/2個數肯定在前n個數當中,而且中位數一定在x陣列的前半部分或者y陣列的後半部分,只要就轉換成在x數 組的前半部分 和y陣列的後半部分找到第(n - n/2)大的元素,可以遞迴求解。
c. 如果x[mid]<y[mid] 分析同上
程式碼如下:
#include<iostream> using namespace std; int find(int *a,int *b,int len) { if(len == 1) return a[0]; int mid = len/2; if(a[mid] == b[mid]) return a[mid]; if(a[mid] < b[mid]) //如果a[mid]較小,那麼說明a[0]-a[mid]肯定屬於合併後陣列前n大的數。 { //剩下的工作就是在a[mid]-a[n]或者,b[0]-b[mid]中找到第n-mid大的元素。 return find(a+mid,b,len-mid); } else { return find(a,b+mid,len-mid); } } int main() { int a[] = {1,3,5,7,9}; int b[] = {10,11,12,13,14}; int len = sizeof(a)/sizeof(a[0]); int result = find(a,b,len); cout<<result<<endl; getchar(); return 0; }