题目
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。算法的时间复杂度应该为 O(log (m+n)) 。
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
第一种:二分
public class FindMedianSortedArrays {
public static void main(String[] args) {
int[] nums1 = {1};
int[] nums2 = {2,3,4,5,6};
System.out.println(new FindMedianSortedArrays().findMedianSortedArrays(nums1, nums2));
}
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
//比如总共6个数,结果是第三第四求平均数,那目标就是找到第三小的和第四小的数
//求中间值 K 总长为 len
//len为奇,left k=len+1/2、right k=len+2/2 向下取整 值一样。len为偶,left k=len+1/2、right k=len+2/2
int len = nums1.length + nums2.length;
int left = getVal((len+1)/2, nums1, 0, nums2, 0);
int right = getVal((len+2)/2, nums1, 0, nums2, 0);
return (left+right)/2.0;
}
private int getVal(int k, int[] nums1, int start1, int[] nums2, int start2) {
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 l = k/2;
int s1 = start1+l-1 >= nums1.length ? Integer.MAX_VALUE : nums1[start1+l-1];
int s2 = start2+l-1 >= nums2.length ? Integer.MAX_VALUE : nums2[start2+l-1];
return s1 < s2 ? getVal(k-l, nums1, start1+l, nums2, start2) : getVal(k-l, nums1, start1, nums2, start2+l);
}
}
LeetCode测试结果
示例代码
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
int left = (m + n + 1) / 2;
int right = (m + n + 2) / 2;
return (getKth(nums1, 0, m - 1, nums2, 0, n - 1, left) + getKth(nums1, 0, m - 1, nums2, 0, n - 1, right)) * 0.5;
}
private double getKth(int[] nums1, int i, int i1, int[] nums2, int i2, int i3, int left) {
int m = i1 - i + 1;
int n = i3 - i2 + 1;
if (m > n) {
return getKth(nums2, i2, i3, nums1, i, i1, left);
}
if (m == 0) {
return nums2[i2 + left - 1];
}
if (left == 1) {
return Math.min(nums1[i], nums2[i2]);
}
int i4 = i + Math.min(m, left / 2) - 1;
int i5 = i2 + Math.min(n, left / 2) - 1;
if (nums1[i4] > nums2[i5]) {
return getKth(nums1, i, i1, nums2, i5 + 1, i3, left - (i5 - i2 + 1));
} else {
return getKth(nums1, i4 + 1, i1, nums2, i2, i3, left - (i4 - i + 1));
}
}
}