LeetCode算法第4题:寻找两个有序数组的中位数

问题描述:

给定两个大小为 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

解题思路:

看到这道题,一个直观的思路就是把两个有序数组合并为一个有序数组 nums3,然后计算这个数组的中位数。

但是这道题要求算法的时间复杂度为 O(log(m + n)),刚才的这个思路就有问题了,因为它的复杂度为O(m + n)。基本上要求时间复杂度为log形式的算法都是采用二分法来进行计算的。两个有序数组 nums1 和 nums2的中位数会把这两个数组合并成的新的有序数组分成两部分,因为数组是有序的,因此前一部分的值肯定是小于后一部分的值的,并且前后两部分的元素都是由nums1 和 nums2中的元素构成的。

基于这个思路,我们把nums1 和 nums2分别进行切分

nums1 -> nums1Left nums1Right

nums2 -> nums2Left nums2Right

nums3 的中位数之前的元素由nums1Left和nums2Left构成,中位数之后的元素由nums1Right和nums2Right构成。

这样的话,寻找两个有序数组的中位数就变成了寻找两个数组的切分位置。而且由于nums1 和 nums2这两个数组的长度是已知的,可以由此计算出中位数的位置,因此这道题目就变成了寻找nums1的切分位置了.

java语言实现:

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
if(nums1.length > nums2.length){
return findMedianSortedArrays(nums2,nums1);
}
int len = nums1.length + nums2.length;
int cut1 = 0;
int cut2 = 0;
int cutL = 0;
int cutR = nums1.length;
while(cut1 <= nums1.length){
cut1 = (cutL + cutR) / 2;
cut2 = len / 2 - cut1;
double L1 = cut1 == 0 ? Integer.MIN_VALUE : nums1[cut1 - 1];
double R1 = cut1 == nums1.length ? Integer.MAX_VALUE : nums1[cut1];
double L2 = cut2 == 0 ? Integer.MIN_VALUE : nums2[cut2 - 1];
double R2 = cut2 == nums2.length ? Integer.MAX_VALUE : nums2[cut2];
if(L1 > R2){
cutR = cut1 - 1;
}else if(L2 > R1){
cutL = cut1 + 1;
}else{
if(len % 2 == 0){
L1 = Math.max(L1,L2);
R1 = Math.min(R1,R2);
return (L1 + R1) / 2;
}else{
return Math.min(R1,R2);
}
}
}

if(len % 2 == 0){
double L1 = nums2[len/2 - nums1.length - 1];
double R1 = nums2[len/2 - nums1.length];
return (L1 + R1) / 2;
}else{
return nums2[len/2 - nums1.length];
}
}
发表评论
留言与评论(共有 0 条评论)
   
验证码:

相关文章

推荐文章

'); })();