4.Median of Two Sorted Arrays
Discription
There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
Examples1
nums1 = [1, 3]
nums2 = [2]
The median is 2.0
Examples2
nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5
分析
- 参考了MissMary网友的思路
https://discuss.leetcode.com/topic/4996/share-my-o-log-min-m-n-solution-with-explanation- 首先,我们分析下求一个已排序数列nums[ ]中位数的方法,如图所示
- 我们定义(half\_len = (len+1)/2);
- 对于偶数长度的数列,(half\_len -1),(half\_len)分别表示中间两个数的位置;
- 而对于奇数长度的数列,(half\_len -1) 恰好是中位数所在位置。
- 下面分析两个已排序的数列的中位数,如下图所示
- 同样求总长度(len = len1+len2;) (quad) 半长度(half\_len = (len+1)/2;)
- 对于两个数列分别找 (i),(j) 位置所在元素;
- 使得 (i + j = half\_len;)
- 当 nums1[i-1] <= nums2[j] 和 nums2[j] <= nums1[i] 同时成立,这时根据(len)的奇偶性来判断中位数就可以了。
- 找(i)的过程采用二分查找的思路
- i 可以取得最小值为 imin = half_len-len2, 最大值为imax = half_len.
- 当 nums[j-1] > nums1[i] 时, i 偏小,将 imin重置为 i + 1,继续查找;
- 当 nums[i-1] > nums2[j] 时, i 偏大,将imax重置为 i - 1 , 继续查找;
- 当以上两种都不满时,则找到了符合条件的 i;
一个数列的中位数如下图所示:
两个数列的中位数如下图所示:
代码
public class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int len1 = nums1.length;
int len2 = nums2.length;
double result=0.0;
if(len1<len2) return findMedianSortedArrays(nums2,nums1);
int len = len1+len2;
if(len==0) return Double.NaN;
if(len==1){
if(len1==1) return nums1[0];
else return nums2[0];
}
int half_len=(len1+len2+1)/2;
int imin=half_len-len2;
int imax=half_len;
int i,j;
while(imin<=imax){
i=(imin+imax)/2;
j=half_len-i;
if(j>0 && i<len1 && nums2[j-1]>nums1[i]){
imin=i+1;
}
else if(j<len2 && i>0 && nums1[i-1]>nums2[j]){
imax=i-1;
}
else{
double max_left, min_right;
if(i==0) max_left=nums2[j-1];
else if(j==0) max_left=nums1[i-1];
else max_left=Math.max(nums1[i-1],nums2[j-1]);
if(i==len1) min_right=nums2[j];
else if(j==len2) min_right=nums1[i];
else min_right=Math.min(nums1[i],nums2[j]);
if(len%2 ==0)
result = (min_right+max_left)/2;
else
result= max_left;
break;
}
}
return result;
}
}