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)).

       You may assume nums1 and nums2 cannot be both empty.

 Approach 1:Recursive Approach

To solve thsi problem, we need to understand "What is the use of median". In statistics, the median is used for:

 If we understand the use of median for dividing, we are very close to the answer.

First let's cut A into two parts at a random position i:

 Since A hs m elements, so there are m+1 kinds of cutting(i=0~m).

And we know:

 With the same way, cut B into two parts at a random position j:

 Put left_A and left_B into one set, and put right_A and right_B into another set. Let's name them left_part and right_part:

 If we can ensure:

 then we divide all elements in {A,B} into two parts with equal length, and one part is always greater than the other. Then

 To ensure these two conditions, we just need to ensure:

 So, all we need to do is:

 And we can do a binary search following steps described below:

 When the object i is found, the median is:

 Now let's consider the edges values i=0,i=m,j=0,j=n where A[i-1],B[j-1],A[i],B[j] may not exist. Actually this situation is easier than you think.

 And in a searching loop, we will encounter only three situations:

 

 So in situation 2. and 3. , we don't need to check whether j>0 and whether j<n.

public double findMedianSortedArrays(int[] nums1,int[] nums2){
        int m=nums1.length;
        int n=nums2.length;
        if(m>n){
               int[] temp=nums1;
               nums1=nums2;
               nums2=temp;
               int tmp=m;
               m=n;
               n=tmp;
        }
        int iMin=0,iMax=m,halfLen=(m+n+1)/2;
        while(iMin<=iMax){
               int i=(iMin+iMax)/2;
               int j=halfLen-i;
               if(i<iMax&&nums2[j-1]>nums1[i]){
                     iMin=i+1;     // i is too small
               }else if(i>iMin&&nums1[i-1]>nums2[j]){
                     iMax=i-1;     // i is too big
               }else{   // i is perfect
                     int maxLeft=0;
                     if(i==0){
                            maxLeft=nums2[j-1];
                     }else if(j==0){
                            maxLeft=nums1[i-1];
                     }else{
                            maxLeft=Math.max(nums1[i-1],nums2[j-1]);
                     }
                     if((m+n)%2==1){
                            return maxLeft;
                     }
                     int minRight=0;
                     if(i==m){
                            minRight=nums2[j];
                     }else if(j==n){
                            minRight=nums1[i];
                     }else{
                            minRight=Math.min(nums2[j],nums1[i]);
                     }
                     return (maxLeft+minRight)/2.0;
               }
        }
        return 0.0;
}

 

 posted on 2020-02-12 20:58  会飞的金鱼  阅读(109)  评论(0)    收藏  举报