一、知识点:
二分查找
二、文字分析:
首先,假设合并后的数组总共有 (m+n) 个元素,其中 m 和 n 分别是牛群 A 和牛群 B 的牛的数量。
如果 (m+n) 是奇数,中位数就是合并后数组的第 ((m+n)/2 + 1) 个元素;
如果 (m+n) 是偶数,中位数就是合并后数组的第 ((m+n)/2) 个元素和第 ((m+n)/2 + 1) 个元素的平均值。
为了达到时间复杂度 O(log (m+n)),我们可以使用二分查找。
在每一次迭代中,我们都要在牛群 A 和牛群 B 的体重数组中各自选取一个位置(假设选取的位置为 i 和 j),将两个子数组分割成四个部分:
leftA | rightA
A[0], A[1], …, A[i-1] | A[i], A[i+1], …, A[m-1]
leftB | rightB
B[0], B[1], …, B[j-1] | B[j], B[j+1], …, B[n-1]
我们需要满足以下两个条件:
- len(leftA) + len(leftB) = len(rightA) + len(rightB),即左侧部分的长度等于右侧部分的长度。
- max(leftA) ≤ min(rightB) 且 max(leftB) ≤ min(rightA),即左侧部分的最大值小于等于右侧部分的最小值。
当满足上述两个条件时,我们就找到了合适的位置 i 和 j,并可以计算出中位数。
三、编程语言:
java
四、正确代码:
public class Solution {
public double findMedianSortedArrays(int[] weightsA, int[] weightsB) {
int m = weightsA.length;
int n = weightsB.length;
if (m > n) {
// 保证 m ≤ n
int[] temp = weightsA;
weightsA = weightsB;
weightsB = temp;
int tmp = m;
m = n;
n = tmp;
}
int iMin = 0, iMax = m;
int halfLen = (m + n + 1) / 2;
while (iMin <= iMax) {
int i = (iMin + iMax) / 2;
int j = halfLen - i;
if (i < m && weightsB[j - 1] > weightsA[i]) {
// i 太小,增大 i
iMin = i + 1;
} else if (i > 0 && weightsA[i - 1] > weightsB[j]) {
// i 太大,减小 i
iMax = i - 1;
} else {
// i 是合适的位置
int maxLeft;
if (i == 0) {
maxLeft = weightsB[j - 1];
} else if (j == 0) {
maxLeft = weightsA[i - 1];
} else {
maxLeft = Math.max(weightsA[i - 1], weightsB[j - 1]);
}
if ((m + n) % 2 == 1) {
// 如果 (m + n) 是奇数,中位数就是 maxLeft
return maxLeft;
}
int minRight;
if (i == m) {
minRight = weightsB[j];
} else if (j == n) {
minRight = weightsA[i];
} else {
minRight = Math.min(weightsA[i], weightsB[j]);
}
// 如果 (m + n) 是偶数,中位数就是 (maxLeft + minRight) / 2
return (maxLeft + minRight) / 2.0;
}
}
return 0.0;
}
}

京公网安备 11010502036488号