给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。
示例 1:
输入: nums1 = [1,3], nums2 = [2]
输出: 2.00000
解释: 合并数组 = [1,2,3] ,中位数 2
示例 2:
输入: nums1 = [1,2], nums2 = [3,4]
输出: 2.50000
解释: 合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
findMedianSortedArrays 方法
- 计算两个数组的总长度
len1和len2。 - 计算中位数的位置
left和right。 - 根据总长度的奇偶性,调用
findKthNumber方法找到第left和right小的数,并计算中位数。
findKthNumber 方法
- 递归地找到两个有序数组合并后的第
k小的数。 - 处理边界情况:如果某个数组已经遍历完,则直接从另一个数组中取值。
- 如果
k为 1,返回两个数组当前起始位置的最小值。 - 计算两个数组的中间值
mid1和mid2,并根据中间值的大小递归调用findKthNumber方法。
public class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int len1 = nums1.length;
int len2 = nums2.length;
int left = (len1 + len2 + 1) / 2;
int right = (len1 + len2 + 2) / 2;
if ((len1 + len2) % 2 == 0) {
return (findKthNumber(nums1, 0, nums2, 0, left) + findKthNumber(nums1, 0, nums2, 0, right)) / 2.0;
} else {
return findKthNumber(nums1, 0, nums2, 0, left);
}
}
public int findKthNumber(int[] nums1, int start1, int[] nums2, int start2, int k) {
if (start1 >= nums1.length) {
return nums2[start2 + k - 1];
}
if (start2 >= nums2.length) {
return nums1[start1 + k - 1];
}
if (k == 1) {
return Math.min(nums1[start1], nums2[start2]);
}
int mid1 = start1 + k / 2 - 1 < nums1.length ? nums1[start1 + k / 2 - 1] : Integer.MAX_VALUE;
int mid2 = start2 + k / 2 - 1 < nums2.length ? nums2[start2 + k / 2 - 1] : Integer.MAX_VALUE;
if (mid1 < mid2) {
return findKthNumber(nums1, start1 + k / 2, nums2, start2, k - k / 2);
} else {
return findKthNumber(nums1, start1, nums2, start2 + k / 2, k - k / 2);
}
}
}