25th Feb: LeetCode 4 Median of Two Sorted Arrays

4. Median of Two Sorted Arrays


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


Example 1:
nums1 = [1, 3]
nums2 = [2]


The median is 2.0


Example 2:
nums1 = [1, 2]
nums2 = [3, 4]


The median is (2 + 3)/2 = 2.5


Thinking: This problem can be solved by two different ways. The most easy way is to merge two different array to one array and find the median immediately. The other way is using a binary search idea. 


First, we can calculate the two mid indexes of two arrays. 

a1, a2, m1, a4, a5

b1, b2, m2, b4, b5


当我们有了这个mid之后,叫m1和m2。接着,我们知道,组合的合并数组会是如下的样子:


当m1小于m2:


{a1, a2, elements from b}, m1, {...}, m2, {b4, b5, elements from a}


所以说唯一不确定就是a4, a5和b1, b2的位置。它们有可能在左边,中间或者右边。


所以,求合并数组的中位数可以转换为求m1, a4, a5和b1, b2, m2的合并数组的中位数。所以可以通过不断地把数组范围缩小。直到:


1)两个中位数相等;


2)两边的数都小于等于2了(两边都是2,两边都是1或者一边是1一边是2)。


但是按照这个思路写出来的程序是残缺的(只能在两边都是奇数的情况下用)


public class Solution {
    private double helper(int[] nums1, int[] nums2, int startOne, int endOne, int startTwo, int endTwo) {
        if (endOne - startOne <= 1 && endTwo - startTwo <= 1) {
            return (Math.max(nums1[startOne], nums2[startTwo]) + Math.min(nums1[endOne], nums2[endTwo])) / 2.0;
        }
        
        int midOne = startOne + (endOne - startOne) / 2;
        int midTwo = startTwo + (endTwo - startTwo) / 2;
        
        if (nums1[midOne] == nums2[midTwo]) {
            return nums1[midOne];
        }
        
        if (nums1[midOne] < nums2[midTwo]) {
            return helper(nums1, nums2, midOne, endOne, startTwo, midTwo);
        } else {
            return helper(nums1, nums2, startOne, midOne, midTwo, endTwo);
        }
    }
    
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        if (nums1.length == 0) {
            return nums2.length % 2 != 0 ? nums2[(0 + nums2.length - 1) / 2] : (nums2[(0 + nums2.length - 1) / 2] + nums2[((0 + nums2.length - 1) / 2) + 1]) / 2.0;
        }
        
        if (nums2.length == 0) {
            return nums1.length % 2 != 0 ? nums1[(0 + nums1.length - 1) / 2] : (nums1[(0 + nums1.length - 1) / 2] + nums1[((0 + nums1.length - 1) / 2) + 1]) / 2.0;
        }
        return helper(nums1, nums2, 0, nums1.length - 1, 0, nums2.length - 1);
    }
}

比较直接的Merge Sorted的方法:


public class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        if (nums1.length == 0) {
            return nums2.length % 2 != 0 ? nums2[(0 + nums2.length - 1) / 2] : (nums2[(0 + nums2.length - 1) / 2] + nums2[((0 + nums2.length - 1) / 2) + 1]) / 2.0;
        }
        
        if (nums2.length == 0) {
            return nums1.length % 2 != 0 ? nums1[(0 + nums1.length - 1) / 2] : (nums1[(0 + nums1.length - 1) / 2] + nums1[((0 + nums1.length - 1) / 2) + 1]) / 2.0;
        }
        
        int i = 0;
        int j = 0;
        int k = 0;
        int limit = 0;
        boolean even = false;
        
        if ((nums1.length + nums2.length) % 2 == 0) {
            limit = ((nums1.length + nums2.length) / 2) + 1;
            even = true;
        } else {
            limit = ((nums1.length + nums2.length) / 2) + 1;
        }
        
        int[] merge = new int[limit];
        
        while (k < limit && i < nums1.length - 1 && j < nums2.length - 1) {
            if (nums1[i] <= nums2[j]) {
                merge[k++] = nums1[i++];
            } else {
                merge[k++] = nums2[j++];
            }
        }
        
        while (k < limit && i < nums1.length - 1) {
            merge[k++] = nums1[i++];
        }
        
        while (k < limit && j < nums2.length - 1) {
            merge[k++] = nums2[j++];
        }
        
        if (even) {
            return ((double)(merge[limit - 2] + merge[limit - 1]) / 2.0);
        } else {
            return merge[limit - 1];
        }
    }
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值