1. 程式人生 > >leetcode之Median of Two Sorted Arrays問題

leetcode之Median of Two Sorted Arrays問題

問題描述:

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

題目示例:

Example 1:

nums1 = [1, 3]
nums2 = [2]

The median is 2.0

Example 2:

nums1 = [1, 2]
nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5

問題來源:Median of Two Sorted Arrays (詳細地址:https://leetcode.com/problems/median-of-two-sorted-arrays/#/description)

問題一般化:由於本題考慮的僅僅是中位數,擴充套件開來,我們可以考慮任意一個第k小的數,這樣將問題一般化,以便編寫大型程式時的模組化處理。

思路:本題的difficulty標記為hard,可想而知還是有一點難度的,個人覺得難點主要是時間複雜度的限制,要求時間複雜度為O(log(m+n))。相反,如果不考慮時間複雜度的話,我們可以考慮一下的方法:

方法一:將兩個數組合並,排序好之後,然後直接取下標為k-1的數即可,即為題目要求的第k小的數;

方法二:動用兩個指標,一個指向(p1)陣列nums1,另外一個(p2)指向陣列nums2,比較兩個指標當前指向的數值的大小,同時動用一個計數器count,比較之後,誰的數值小誰就               往前移。計數器加一,直到count的值加到k則遍歷結束。

上面兩種方法其實都不符合題意,最後在下面這篇文章找到了正確答案(Median of Two Arrays)。原文用的是英文解釋和表述的,並且給出了相應的證明,本人只負責簡單的翻譯一下。

假定兩個陣列中的陣列個數均多於k/2個(程式碼中解釋為什麼多餘k/2個,暫時先往下看吧),咱們分別把兩個陣列中的第k/2-1個取出來,分別記作A[k/2 - 1]和B[k/2 -1],把他們進行比較,有三個結果(這不是廢話嗎?)

A[k/2 - 1]  <  B[k/2 - 1]

A[k/2 - 1]  =  B[k/2 - 1]

A[k/2 - 1]  >  B[k/2 - 1]

下面考慮第一種情況,A的第k/2個數(陣列下標為k/2 - 1)比B的第k/2個數要小,說明當A和B合併之後,A的下標從0到k/2 - 1之間的數都不可能是第K大的數,顯然咱們可以將它們剔除掉,有些人可能立馬就想到了,這不就是二分查詢的思想嗎?我可以說是的,就是這麼個意思。大於的情況是一樣討論的;等於的話打就更好了,不就直接就找到了嗎?免得那麼麻煩。有人可能現在產生疑惑了,奇數個和偶數個需要分開來討論嗎?其實是沒必要的,合併之後是奇數個的話咱們直接就取正中間的那個,合併之後如果有偶數個數的話,咱們就將兩個數加起來除以2.0不就OK啦。

下面我們來考慮一下遞迴的邊界條件:

1)如果其中有一個數組是空的話,那麼就直接返回另外一個數組的下標為[k - 1]的就可以了;

2)如果k = 1,也就是說取的是最小值,我們只需要比較A[0]和B[0],然後取他們之間更小的值就行了唄;

3)如果A[k/2 -  1] = B[k/2 - 1],當然只需要返回其中的一個就行了。

OK,分析到此為止,下面開始動手啦!!!

程式碼:

按題目要求,陣列個數分為偶數個和奇數個的情況:

下面就是具體的查詢第k大的數的描述了:

這道題第一次見還是比較新穎的,在這參考了下面的這篇部落格,就是我上文提到的那篇文章,在這以表感謝啊(http://blog.csdn.net/zxzxy1988/article/details/8587244)。