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)).java
給你兩個排序數組,容量爲m的數組A,容量爲n的數組B。求出兩個數組的中位數(啥玩意?),硬性要求時間複雜度O(log (m+n)).算法
1:太汗顏了,median究竟是個啥,查一下:數組
中位數是在一組數據中居於中間的數(特別注意的地方是:這組數據以前已經通過升序排列!!!),即在這組數據中,有一半的數據比它大,有一半的數據比它小。若是這組數據包含偶數個數字,中值是位於中間的兩個數的平均值。spa
2:好吧,中位數是這麼個玩意,那麼理論上首先咱們須要先將兩個數組合爲一,再求這個新合併的數組的中位數。翻譯
3:可是,已經限定死了時間複雜度爲log(m+n),原來LeetCode的題目也思路不開放嘛。code
4:問題能夠轉化成兩個有序序列找第num大的數,因爲時間複雜度已經限定死了,只能採用相似二分的思想,每一個步驟去掉一半數據元素。排序
public class MedianofTwoSortedArrays2 { //先來一個蠢的,實現功能。其實效率仍是能夠的嘛,只不過不符合算法要求,時間複雜度在於排序的 n*log(n) public static double findMedianLow(int A[], int B[]) { int[] sumArray = ArrayUtils.addAll(A, B); Arrays.sort(sumArray); int length = sumArray.length; if (length % 2 == 0) { double num1 = sumArray[length / 2]; double num2 = sumArray[length / 2 - 1]; return (num1 + num2) / 2; } else { return sumArray[length / 2]; } } public static double findMedianSortedArrays(int A[], int B[]) { int m = A.length; int n = B.length; int total = m + n; //長度爲積數取中間,爲偶數去中間兩個的平均值 if ((total & 0x01) != 0) { return findMedian(A, m, B, n, total / 2 + 1); } else { return (findMedian(A, m, B, n, total / 2) + findMedian(A, m, B, n, total / 2 + 1)) / 2.0; } } //二分法,每次都能去除掉一部分範圍外數據。須要注意每次去除數據都會改變數組的結構,因此須要特殊處理臨界值 private static double findMedian(int A[], int m, int B[], int n, int target) { if (m == 0) { return B[target - 1]; } else if (n == 0) { return A[target - 1]; } else if (target == 1) { return A[0] < B[0] ? A[0] : B[0]; } int temp = target / 2; if (Math.min(m, n) < temp) { temp = Math.min(m, n); } if (A[temp - 1] > B[temp - 1]) { return findMedian(A, m, Arrays.copyOfRange(B, temp, n), n - temp, target - temp); } else if (A[temp - 1] < B[temp - 1]) { return findMedian(Arrays.copyOfRange(A, temp, m), m - temp, B, n, target - temp); } else { return A[temp - 1]; } } public static void main(String[] args) { int[] a = new int[10000]; int[] b = new int[20000]; for (int i = 0; i < 10000; i++) { a[i] = i + 1; } for (int i = 10000; i < 30000; i++) { b[(i - 10000)] = i + 1; } long nowTime = System.currentTimeMillis(); System.out.println(MedianofTwoSortedArrays2.findMedianLow(a, b)); System.out.println(System.currentTimeMillis() - nowTime); long nowTime1 = System.currentTimeMillis(); System.out.println(MedianofTwoSortedArrays2.findMedianSortedArrays(a, b)); System.out.println(System.currentTimeMillis() - nowTime1); } }