Median of Two Sorted Arrays

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

解法1: merge sort (O(m+n))

Analysis

  • Merge two arrays to a new array (merge sort)
  • Find the median for odd and even case

Code

public class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        if ((nums1==null || nums1.length==0) && (nums2==null || nums2.length==0)) return -1.0;

        int len1 = (nums1==null) ? 0 : nums1.length;
        int len2 = (nums2==null) ? 0 : nums2.length;
        int len = len1+len2;

        int[] merge = new int[len];
        int index1=0, index2=0, index3=0;

        while (index1<len1 && index2<len2){
            if (nums1[index1]<nums2[index2]) {merge[index3++]=nums1[index1++];}
            else {merge[index3++]=nums2[index2++];}
        }

        if (index1==len1){
            while (index2<len2) {merge[index3++]=nums2[index2++];}
        }
        else {
            while (index1<len1) {merge[index3++]=nums1[index1++];}
        }

        if (len%2==0){return (merge[len/2]+merge[len/2-1])/2.0;}
        else {return merge[len/2];}
    }
}

Note

  • 注意最后return的时候除以2.0才能return double,如果写成2的话只return int

解法2: binary search (Olog(m+n))

  • find kth number:
    • 如果nums1[k/2] < nums2[k/2],合并后的前k的数一定包括nums1的多于前k/2个数和nums2的少于前k/2个数,说明nums1的前k/2个数一定在合并后的前k个数里。那么相当于从nums1的k/2开始,nums2的0开始合并,找第k-k/2个数。
    • 同理nums1[k/2]>nums2[k/2]的情况
    • 如果nums1的长度小于k/2,那么nums2的前k/2个数必须在合并后的前k个数里,放弃nums2的前k/2个数
    • 同理对于nums2的长度小于k/2的情况

Code

public class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int len = nums1.length + nums2.length;
        if (len%2==0){
            return (findKth(nums1, 0, nums2, 0, len/2)+findKth(nums1, 0, nums2, 0, len/2+1))/2.0;
        }
        else {
            return findKth(nums1, 0, nums2, 0, len/2+1);
        }
    }

    //find kth number of two sorted array
    private int findKth(int[] nums1, int index1, int[] nums2, int index2, int k){
        if (index1 >= nums1.length) return nums2[index2+k-1]; 
        if (index2 >= nums2.length) return nums1[index1+k-1];
        if (k==1) return Math.min(nums1[index1], nums2[index2]);

        int key1 = index1+k/2-1 >= nums1.length ?  Integer.MAX_VALUE : nums1[index1+k/2-1];
        int key2 = index2+k/2-1 >= nums2.length ?  Integer.MAX_VALUE : nums2[index2+k/2-1];

        if (key1 < key2){
            return findKth(nums1, index1+k/2, nums2, index2, k-k/2);
        }
        else {
            return findKth(nums1, index1, nums2, index2+k/2, k-k/2);
        }
    }
}

Reference

  • Yuanbin
  • 九章算法课video (course 2)