给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。
请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1 和 nums2 不会同时为空。
示例 1:
nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0
示例 2:
nums1 = [1, 2]
nums2 = [3, 4]
则中位数是 (2 + 3)/2 = 2.5
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
/* 寻找中位数,可以看成寻找一条分割线,使分割线两侧,左边小于右边
* 当数组长度为奇数时,我们让左边元素多一个,则此时,中位数为左边两个最大数的最大值
* 当数组长度为偶数时,中位数为左边最大值和右边最小值的平均数
*/
// 为了使第二个数组右边总是有值,当nums1长度大于nums2长度时,我们交换两个引用
if(nums1.length > nums2.length) {
int[] temp = nums1;
nums1 = nums2;
nums2 = temp;
}
// 左边所有元素需要满足的个数
int totalLeft = (nums1.length + nums2.length + 1) / 2;
// 分割线寻找的左右边界
int left = 0, right = nums1.length;
while(left < right) {
// 取左右边界平均(二分)作为i,则第二个数组左边元素个数为j
// 加1为了两个元素时不进入死循环
int i = (left + right + 1) / 2, j = totalLeft - i;
// 数组1左边最大值的数值大于数组2右边最小值,此时分割线需要左移
if (nums1[i - 1] > nums2[j]) {
right = i - 1;
} else {
// 反面
left = i;
}
}
// 重新定义分割线
int i = left, j = totalLeft - i;
// 分别得到nums1 nums2左边最大值和右边最小值(需要考虑边界情况)
int nums1LeftMax = i == 0 ? Integer.MIN_VALUE : nums1[i - 1];
int nums1RightMin = i == nums1.length ? Integer.MAX_VALUE : nums1[i];
int nums2LeftMax = j == 0 ? Integer.MIN_VALUE : nums2[j - 1];
int nums2RightMin = j == nums2.length ? Integer.MAX_VALUE : nums2[j];
// 数组长度为奇数,返回左边最大值,偶数返回左边最大值和右边最小值的平均数
if ((nums1.length + nums2.length) % 2 == 1) {
return Math.max(nums1LeftMax, nums2LeftMax);
} else {
return (double)(Math.max(nums1LeftMax, nums2LeftMax) + Math.min(nums1RightMin, nums2RightMin)) / 2;
}
}
}
京公网安备 11010502036488号