题目地址: 链接
思路: 要想O(log(n + m))时间复杂度内实现当前算法。很显然是二分算法,而且需要将两个数组成为一个整体来想。
两个数组都是递增的,并且中位数的左边的内容是一样的,如果将问题转换为获取中位数的下标,那么思路就很清晰了。
- 获取两个数组下标。在 nums1 中选取一个下标
mid - 1,由于是两个数组的中位数,而且是两个有序数组,所以另外一个数组的下标是确定的totalN - mid - 1 - 选取两个下标的最大值,判断是否大于
nums[q1 + 1],如果成立,说明当前成立,可以让左收拢;反之向右收拢。 - 重复1,知道 l < r 不成立
- 根据 n + m 的奇偶性来返回对应的中位数。
js
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number}
*/
var findMedianSortedArrays = function(nums1, nums2) {
function check_left(mid) {
if(mid > n) return false;
if(totalN - mid > m) return true;
let [q1, q2] = [mid - 1, totalN - mid - 1];
let maxValue = -Infinity;
if(q1 >= 0) maxValue = Math.max(nums1[q1], maxValue);
if(q2 >= 0) maxValue = Math.max(nums2[q2], maxValue);
if(q1 + 1 < n && maxValue > nums1[q1 + 1]) return true;
return false;
}
let [n, m] = [nums1.length, nums2.length];
let totalN = n + m + 1 >> 1;
let isOdd = (n + m) % 2;
let [l, r] = [0, totalN];
while(l < r) {
let mid = l + r >> 1;
if(check_left(mid)) l = mid + 1;
else r = mid;
}
let ans = -Infinity;
let [idx1, idx2] = [l - 1, totalN - l - 1]
if(idx1 >= 0) ans = Math.max(ans, nums1[idx1]);
if(idx2 >= 0) ans = Math.max(ans, nums2[idx2]);
if(!isOdd) {
let otherNum = Infinity
if(l < n) {
otherNum = Math.min(otherNum, nums1[l]);
}
if(totalN - l < m) {
otherNum = Math.min(otherNum, nums2[totalN - l]);
}
ans = (ans + otherNum) / 2;
}
return ans;
};