参照点击打开链接
用二叉搜索来处理此题
以如下两个数组为例:
0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
a0 | a1 | a2 | a3 | a4 | a5 |
0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
b0 | b1 | b2 | b3 | b4 | b5 |
本题中,中间坐标由 mid = length / 2得出,A,B的中间坐标分别是A[3], B[3]. 于是将其分为如下两个部分
A_1(A[0], A[1], A[2]), A_2(A[3], A[4], A[5])
B_1(B[0], B[1], B[2]), B_2(B[3], B[4], B[5]).
接下来比较A[3] 和 B[3].
如果 A[3] <= B[3], B_2部分一定大于等于B_1和A_1中的任意元素. 如果要在两个数组中找到第K个元素,会有如下两种情况.
- 如果K小于A_1和B_1长度之和,那么K元素定不在B_2中。则下次搜索K元素,只在A和B_1中。
- 如果K大于A_1和B_1长度之和,那么K元素定不在A_1中,否则,K小于A_1和B_1长度之和。同时在A_2和B中,查找第K-A_1长度个元素.
同理考虑 A[3] > B[3].
/**
* @param A: An integer array.
* @param B: An integer array.
* @return: a double whose format is *.5 or *.0
*/
public double findMedianSortedArrays(int A[], int B[]) {
int la = A.length;
int lb = B.length;
int sum = la + lb;
if (sum % 2 == 0) {
double ln = (double)findKthNum( A, 0, la, B, 0, lb, (la + lb)/2);
double rn = (double)findKthNum(A, 0, la, B, 0, lb, (la + lb)/2 + 1);
return (ln + rn)/2;
} else {
return (double)findKthNum( A, 0, la, B, 0, lb, (la + lb + 1)/2);
}
}
private int findKthNum(int A[], int sa, int ea, int B[], int sb, int eb, int k) {
int la = ea - sa;
int lb = eb - sb;
if (la <= 0) {
return B[sb + k -1];
}
if (lb <= 0) {
return A[sa + k -1];
}
if (k == 1) {
return A[sa] < B[sb] ? A[sa] : B[sb];
}
int midA = (sa + ea)/2;
int midB = (sb + eb)/2;
if (A[midA] < B[midB]) {
if (la/2 + lb/2 + 1 >= k) {
return findKthNum(A, sa, ea, B, sb, midB, k);
} else {
return findKthNum(A, midA + 1, ea, B, sb, eb, k - la/2 - 1);
}
} else {
if (la/2 + lb/2 + 1 >= k) {
return findKthNum(A, sa, midA, B, sb, eb, k);
} else {
return findKthNum(A, sa, ea, B, midB + 1, eb, k - lb/2 - 1);
}
}
}
// public double findMedianSortedArrays(int[] A, int[] B) {
// // write your code here
// int []array = new int [A.length + B.length];
// int i = 0, j = 0, k = 0;
// for (; i < A.length && j < B.length; ) {
// if (A[i] <= B[j]) {
// array[k] = A[i];
// i++;
// } else {
// array[k] = B[j];
// j++;
// }
// k++;
// }
// while (i < A.length) {
// array[k] = A[i];
// i++;
// k++;
// }
// while (j < B.length) {
// array[k] = B[j];
// j++;
// k++;
// }
// //1 int length = array.length;
// //2 int length = array.length - 1;
// int length = array.length;
// if (length % 2 == 0) {
// // int left = (length - 1) / 2;
// // int right = left + 1;
// int right = length/2;
// int left = right - 1;
// //3 return (array[left] + array[right])/2;
// return (array[left] + array[right])/2.0;
// } else {
// return array[length / 2];
// }
// }