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); } }