Median of Two Sorted Array leetcode java

愛做飯的小瑩子發表於2014-07-23

題目:

There are two sorted arrays A and B 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)).

 

 題解:

首先我們先明確什麼是median,即中位數。

引用Wikipedia對中位數的定義:

計算有限個數的資料的中位數的方法是:把所有的同類資料按照大小的順序排列。如果資料的個數是奇數,則中間那個資料就是這群資料的中位數;如果資料的個數是偶數,則中間那2個資料的算術平均值就是這群資料的中位數。

因此,在計算中位數Median時候,需要根據奇偶分類討論。

解決此題的方法可以依照:尋找一個unioned sorted array中的第k大(從1開始數)的數。因而等價於尋找並判斷兩個sorted array中第k/2(從1開始數)大的數。

特殊化到求median,那麼對於奇數來說,就是求第(m+n)/2+1(從1開始數)大的數。

而對於偶數來說,就是求第(m+n)/2大(從1開始數)和第(m+n)/2+1大(從1開始數)的數的算術平均值。


那麼如何判斷兩個有序陣列A,B中第k大的數呢?

我們需要判斷A[k/2-1]和B[k/2-1]的大小。

如果A[k/2-1]==B[k/2-1],那麼這個數就是兩個陣列中第k大的數。

如果A[k/2-1]<B[k/2-1], 那麼說明A[0]到A[k/2-1]都不可能是第k大的數,所以需要捨棄這一半,繼續從A[k/2]到A[A.length-1]繼續找。當然,因為這裡捨棄了A[0]到A[k/2-1]這k/2個數,那麼第k大也就變成了,第k-k/2個大的數了。

如果 A[k/2-1]>B[k/2-1],就做之前對稱的操作就好。

 這樣整個問題就迎刃而解了。

 

當然,邊界條件頁不能少,需要判斷是否有一個陣列長度為0,以及k==1時候的情況。

 

因為除法是向下取整,並且頁為了方便起見,對每個陣列的分半操作採取:

int partA = Math.min(k/2,m);
int partB = k - partA;

 為了能保證上面的分半操作正確,需要保證A陣列的長度小於B陣列的長度。

 

同時,在返回結果時候,注意精度問題,返回double型的就好。

 

程式碼如下:

 1 public static double findMedianSortedArrays(int A[], int B[]) {
 2     int m = A.length;
 3     int n = B.length;
 4     int total = m+n;
 5     if (total%2 != 0)
 6         return (double) findKth(A, 0, m-1, B, 0, n-1, total/2+1);//k傳得是第k個,index實則k-1
 7     else {
 8         double x = findKth(A, 0, m-1, B, 0, n-1, total/2);//k傳得是第k個,index實則k-1
 9         double y = findKth(A, 0, m-1, B, 0, n-1, total/2+1);//k傳得是第k個,index實則k-1
10         return (double)(x+y)/2;
11     }
12 }
13  
14 public static int findKth(int[] A, int astart, int aend, int[] B, int bstart, int bend, int k) {
15     int m = aend - astart + 1;
16     int n = bend - bstart + 1;
17     
18     if(m>n)
19         return findKth(B,bstart,bend,A,astart,aend,k);
20     if(m==0)
21         return B[k-1];
22     if(k==1)
23         return Math.min(A[astart],B[bstart]);
24     
25     int partA = Math.min(k/2,m);
26     int partB = k - partA;
27     if(A[astart+partA-1] < B[bstart+partB-1])
28         return findKth(A,astart+partA,aend,B,bstart,bend,k-partA);
29     else if(A[astart+partA-1] > B[bstart+partB-1])
30         return findKth(A,astart,aend,B,bstart+partB,bend,k-partB);
31     else
32         return A[astart+partA-1];
33     }

 Reference:

http://blog.csdn.net/yutianzuijin/article/details/11499917

http://blog.csdn.net/linhuanmars/article/details/19905515

相關文章