演算法分析與設計 第六周 兩個排序陣列的中位數

2021-08-29 01:15:33 字數 2612 閱讀 8456

4.核心**

5.結果

6.源**

本週為兩節習題課,在習題課的最後,討論到了這一題,沒有討論出結果。本來有一些思路,恰好看到了這一題,於是將其解決。

這道題本來解法不難,正常思路有兩種,一種是直接講兩個陣列排序,然後直接找到中間數值,其演算法複雜度為o(m + n);另一種是從兩個陣列的首部開始找,每找到乙個小數,指標就向下移動一格,直到移動了(m + n) / 2其複雜度也為o(m + n)。因此兩種演算法都不符合題目o(log(m + n))的要求。

我們看題目要求,很容易聯想到,log的複雜度,說明要用到二分之類的方法。將本題模擬做尋找k值,(k = (m + n) / 2)。認真思考,二分的實質即是:每次剔除一般的值,一次遞迴,一直剔除到需要的值出現。如果是在乙個陣列中尋找,很簡單,每次將兩份數值中的乙份刪去即可,但是如果是兩個陣列,那又如何實現呢?

想象將兩個陣列同時二分,分成4段,能否得到可定可以刪去的一段呢?是可以的,舉個簡單的例子:

我們來比較xy的大小,如果x > y那麼就說明mid n左邊的一段一定是可以刪去的,若是x < y,那麼結果相反,刪去的即是mid m左邊的一段。一次操作過後,剩下的即是在剩下的三段中間找尋k - mid n/mid m大的值。

那麼新的問題又出現了:如果在遞迴的過程中,某一段的mid m/mid n > k了應該怎麼辦?其實也很好解決,在我們二分的時候,將步長設定為k / 2即可。

現在考慮,完整的演算法應該如何劃分,選擇。

這樣,每次我們就能夠從中間刪除k / 2長度的區間。

但是我們的問題又來了,如果陣列不夠k / 2的長度呢?不就會越界訪問了嗎?因此,區間設定應該為min(k / 2, m_length, n_length)

接下來,我們要思考,終點在**。實際上,終點就是k == 1或者m\n長度為0的時候。

(m + n)是奇數,尋找(m + n) / 2;否則尋找((m + n) / 2 + (m + n) / 2 + 1) / 2

尋找k位演算法:

//如果有陣列為空,在剩下的陣列中尋找即可

if (mlen == 0) else if (nlen == 0)

//只找一位,避免死迴圈

if(k == 1)

int mmid, nmid;

//避免越界,又要保證刪去盡可能多的資料,因此選擇長的陣列作為起始分界點

if (nlen > mlen) else

//判斷

//只找一位,避免死迴圈

if(k == 1)

int mmid, nmid;

//避免越界,又要保證刪去盡可能多的資料,因此選擇長的陣列作為起始分界點

if (nlen > mlen) else

//判斷

if(m[mstart + mmid - 1] < n[nstart + nmid - 1]) else else

} }

演算法分析與設計(第六周) 更新中

本週知識要點 6.1 子串行和定義 定長子序列和演算法 不定長子序列和演算法,最大子串行和演算法 子串行積演算法 6.2 找主元演算法 遞迴,分段處理 附加數學證明 問題描述 給一段數列 m 子串行定長 n 問何時子串行和最大。思路 運用兩重迴圈 一重迴圈用來移動視窗 即起始位置 第二重迴圈求和。此...

系統分析與設計第六周作業

二 建模練習題 確定系統邊界,寫明系統名稱 確定參與者 確定參與者之間的關係 根據需求創造用例 確定參與者與用例之間的關係 確定用例與用例之間的關係 將其他支援用例的系統放置在系統框的右邊 為什麼相似系統的用例圖是相似的?答 因為在相似的系統中,使用者需求是相似的,對應的用例場景也相似,所以用例圖也...

mooc程式設計與演算法(三)第六周 多型

派生類的指標可以賦值給基類指標 通過基類指標用基類和派生類中的同名虛函式時 若該指標指向乙個基類的物件,那麼被呼叫是基類的虛函式 若該指標指向乙個派生類的物件,那麼被呼叫的是派生類的虛函式。派生類的物件可以賦值給基類的引用 通過基類引用呼叫基類和派生類中的同名虛函式時 若該引用引用的是乙個基類的物件...