兩個有序陣列求合併後,求其中位數?

2021-07-02 05:17:20 字數 2695 閱讀 2405

第一步:假設兩個有序陣列(已經各自排序完成了)長度相等,試寫函式找出兩個陣列合併後的中位數?

第二步:假設兩個有序陣列長度不等,一樣的求出中位數?

思想是二分查詢。。。

解析: 這個題目看起來非常簡單。第一題的話: 假設陣列長度為n, 那麼我就把陣列1和陣列2直接合併,然後再直接找到中間元素。對於這樣的方案,第一題和第二題就沒有什麼區別了。這樣的話時間複雜度就是o(n)。通常在這樣的情況下,那些mentor型別的達人就會循循善誘道:「你還有更好的辦法嗎:)」 如果比線性更高效,直接能想到的就是對數了o(log(n)),這個時間複雜度在這裡可能嗎? 當然還是可能的。來繼續看看下面的分析。

先找來了乙個圖:

馬上有人說那不定長的怎麼辦呢?一樣的,我們還是來畫個圖看看:

一樣的, 我們還是把這個兩個陣列來比較一下,不失一般性,我們假定b陣列比a陣列長一點。a的長度為n, b的長度為m。比較a[n/2]和b[m/2] 時候。類似的,我們還是分成幾種情況來討論:

a. 如果a[n/2] == b[m/2],那麼很顯然,我們的討論結束了。a[n/2]就已經是中位數,這個和他們各自的長度是奇數或者偶數無關。

b. 如果a[n/2] < b[m/2],那麼,我們可以知道這個中位數肯定不在[a[0],a[n/2])這個區間內,同時也不在[b[m/2],b[m]]這個區間裡面。這個時候,我們不能衝動地把[a[0],a[n/2])和[b[m/2],b[m]]全部扔掉。我們只需要把[b[m-n/2],b[m]]和[a[0],a[n/2])扔掉就可以了。(如圖所示的紅色線框),這樣我們就把我們的問題成功轉換成了如何在a[n/2]->a[n]這個長度為n/2的陣列和b[1]-b[m-n/2]這個長度為m-n/2的陣列裡面找中位數了。問題複雜度即可下降了。

c. 只剩下a[n/2] > b[m/2],和b類似的,我們可以把a[n/2]->a[n]這塊以及b[1]->b[n/2]這塊扔掉了就行,然後繼續遞迴。

我們也可以寫下如下的**:

int find_median_random_length( int a, int lengtha, int b, int

lengthb)

else

return

b[nb];

}else

if (lengthb == 1

)

else

return

a[ma];

}if ( a[ma] ==b[nb] )

return

a[ma];

else

if ( a[ma]

return find_median_random_length(&a[ma],lengtha-l,&b[0],lengthb-l);

else

return find_median_random_length(&a[0],lengtha-l,&b[nb],lengthb-l);

}

在一些特定的case下面測試了一下,結果還是正確的,下面是用的testcase

int _tmain(int argc, _tchar*argv)

;

int b = ;

std::cout

<

median for equal length is :

"int c = ;

int d = ;

std::cout

<

median for equal length is :

"int a=;

int b=;

int sizea = sizeof(a)/sizeof(int

);

int sizeb = sizeof(b)/sizeof(int

);

std::cout

<

median :

"<:endl>

int c = ;

int d = ;

std::cout

<

median :

"system(

"pause");

return0;

}

擴充套件: 

m個長度為n的排序好的陣列 求中位數 

目前有兩個比較好的演算法 

演算法一 

(1)取所有陣列的最小值和最大值,求出全體的最大值和最小值min max 然後取m=(min+max)/2 

(2)用m在所有陣列中搜尋 找到比m小的數的個數n1 若n1大於m*n/2 則mid=(min+mid)/2 否則mid=(mid+max)/2 

(3)重複上述搜尋一共迴圈log(max-min)次 

演算法二 

(1)取所有陣列的中值排序 

棄掉這個最大值所在陣列的後半部分和最小值所在陣列的前半部分 再將這兩個只剩一半的陣列合併 o(n) 

(2)從合併後的陣列中找出中值插入到之前的中值排序陣列裡 o(logn) 

(3)重複(1)(2),每次迴圈可以捨掉乙個陣列,一共需要迴圈m次

求兩個有序陣列的中位數

要求 給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2。請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 o log m n 例如 nums1 1,3 nums2 2 則中位數是 2.0 nums1 1,2 nums2 3,4 則中位數是 2 3 2 2.5 演算法解析...

求兩個有序陣列的中位數

原部落格 設陣列a的長度為m,陣列b的長度為n,兩個陣列都都是遞增有序的。求這兩個陣列的中位數 首先我們看看中位數的特點,乙個大小為n的陣列,如果n是奇數,則中位數只有乙個,陣列中恰好有 n 1 2 個元素比中位數小。如果n是偶數,則中位數有兩個 下中位數和上中位數 這裡我們只求下中位數,對於下中位...

兩個有序陣列中位數

大小m和n分別有兩個排序陣列a和b。找到兩個排序陣列的中值。總的執行時間複雜度應該是o log m n class solution return findkth a,b,0,0,m,n,s 2 findkth a,b,0,0,m,n,s 2 1 2 private double findkth v...