①原题
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)).
②乡村英语翻译一下
给你两个排序数组,容量为m的数组A,容量为n的数组B。求出两个数组的中位数(啥玩意?),硬性要求时间复杂度O(log (m+n)).
③读题
1:太汗颜了,median到底是个啥,查一下:
中位数是在一组数据中居于中间的数(特别注意的地方是:这组数据之前已经经过升序排列!!!),即在这组数据中,有一半的数据比它大,有一半的数据比它小。如果这组数据包含偶数个数字,中值是位于中间的两个数的平均值。
2:好吧,中位数是这么个玩意,那么理论上首先我们需要先将两个数组合为一,再求这个新合并的数组的中位数。
3:但是,已经限定死了时间复杂度为log(m+n),原来LeetCode的题目也思路不开放嘛。
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]
}
int temp = target / 2;
if (Math.min(m, n)
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]
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
a[i] = i + 1;
}
for (int i = 10000; 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);
}
}