題目:
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型的就好。
程式碼如下:
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