leetcode 4-Median of Two Sorted Arrays(hard)

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.

two pointers, one point i at nums1, one point j at nums2, the number of numbers on the left is equal or less than the numbers on the right. Once pointer i fixed, pointer j can be fixed.

In order to make sure j is positive, first check which one is shorter, and switch nums1 and nums2 if nums2 is shorter.

In an array with n numbers, there are n+1 positions where we can seperate the array in half, so we set lo=0, hi=len1(len1<len2), and use binary search to find a partition place in the shorter array(the longer array can be partitioned accordingly), so that the left part of it will be less or equal to the right part.

i=(lo+hi)/2, j=(len1+len2+1)/2(note: +1 is set to make the solution satisfy odd cases(when len1+len2 is odd, number of left part will be number of right part plus 1, so the median is the maximum of left part.)

i, j=(len1+len2+1)/2-i 

1. nums1[i-1]>nums2[j], hi=m-1;

2. nums[j-1]>nums2[i], lo==m+1;

3. get the right partition position.

如果到了边界就相应的设置为Integer.MAX_VALUE或Integer.MIN_VALUE.

https://www.youtube.com/watch?v=LPFhl65R7ww 不明白可以看这个视频,讲的很清楚。复杂度是O(log(min(len1,len2))。

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int len1=nums1.length;
        int len2=nums2.length;
        if(len1>len2) return findMedianSortedArrays(nums2, nums1);
        int lo=0,hi=nums1.length;
        while(lo<=hi){
            int i=(lo+hi)/2;
            int j=(len1+len2+1)/2-i;
            int left1= i==0?Integer.MIN_VALUE:nums1[i-1];
            int left2= j==0?Integer.MIN_VALUE:nums2[j-1];
            int right1= i==len1?Integer.MAX_VALUE:nums1[i];
            int right2= j==len2?Integer.MAX_VALUE:nums2[j];
            if(left1<=right2&&left2<=right1){
                if((len1+len2)%2==1) return Math.max(left1,left2);
                else return (Math.max(left1,left2)+Math.min(right1,right2))/2.0;
            }
            else if(left1>right2) hi=i-1;
            else lo=i+1;
        }
        return -1;
    }
}

这道题如果不这样把情况统一起来,corner case 会非常繁琐复杂,很容易出错。

猜你喜欢

转载自www.cnblogs.com/yshi12/p/9697638.html