4.Median of Two Sorted Arrays

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

分析

  1. 参考了MissMary网友的思路
    https://discuss.leetcode.com/topic/4996/share-my-o-log-min-m-n-solution-with-explanation
  2. 首先,我们分析下求一个已排序数列nums[ ]中位数的方法,如图所示
  • 我们定义\(half\_len = (len+1)/2\)
  • 对于偶数长度的数列,\(half\_len -1\)\(half\_len\)分别表示中间两个数的位置;
  • 而对于奇数长度的数列,\(half\_len -1\) 恰好是中位数所在位置。
  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;
    }
}
posted @ 2017-04-13 21:46  gexin1023  阅读(166)  评论(0编辑  收藏  举报