class Solution {
public double findMedianSortedArrays(int[] A, int[] B) {
int m = A.length;
int n = B.length;
if (m > n) {
return findMedianSortedArrays(B,A); // 保证 m <= n
}
int iMin = 0, iMax = m;
while (iMin <= iMax) {
int i = (iMin + iMax) / 2;
int j = (m + n + 1) / 2 - i;
if (j != 0 && i != m && B[j-1] > A[i]){ // i 需要增大
iMin = i + 1;
}
else if (i != 0 && j != n && A[i-1] > B[j]) { // i 需要减小
iMax = i - 1;
}
else { // 达到要求,并且将边界条件列出来单独考虑
int maxLeft = 0;
if (i == 0) { maxLeft = B[j-1]; }
else if (j == 0) { maxLeft = A[i-1]; }
else { maxLeft = Math.max(A[i-1], B[j-1]); }
if ( (m + n) % 2 == 1 ) { return maxLeft; } // 奇数的话不需要考虑右半部分
int minRight = 0;
if (i == m) { minRight = B[j]; }
else if (j == n) { minRight = A[i]; }
else { minRight = Math.min(B[j], A[i]); }
return (maxLeft + minRight) / 2.0; //如果是偶数的话返回结果
}
}
return 0.0;
}
}
-
int m = A.length; int n = B.length;
:获取两个数组的长度。
-
if (m > n) { return findMedianSortedArrays(B,A); }
:为了保证 m <= n,如果 m > n,我们就调用自己并将两个数组交换位置。
-
int iMin = 0, iMax = m;
:初始化 i 的搜索范围。
-
while (iMin <= iMax) { ... }
:开始二分查找。
-
int i = (iMin + iMax) / 2;
:计算当前的 i。
-
int j = (m + n + 1) / 2 - i;
:计算对应的 j。
-
if (j != 0 && i != m && B[j-1] > A[i]) { iMin = i + 1; }
:如果 B[j-1] > A[i],说明 i 太小了,我们需要增大 i。
-
else if (i != 0 && j != n && A[i-1] > B[j]) { iMax = i - 1; }
:如果 A[i-1] > B[j],说明 i 太大了,我们需要减小 i。
-
else { ... }
:如果找到了合适的 i,我们就计算中位数。
int maxLeft = ...;
:计算左边的最大值。if ( (m + n) % 2 == 1 ) { return maxLeft; }
:如果总数是奇数,直接返回 maxLeft。int minRight = ...;
:计算右边的最小值。return (maxLeft + minRight) / 2.0;
:如果总数是偶数,返回左边最大值和右边最小值的平均值。
-
return 0.0;
:默认返回值,实际上这段代码永远不会执行到这一步。