Search code examples
algorithmdata-structurestime-complexitymedian

Finding median in merged array of two sorted arrays


Assume we have 2 sorted arrays of integers with sizes of n and m. What is the best way to find median of all m + n numbers?

It's easy to do this with log(n) * log(m) complexity. But i want to solve this problem in log(n) + log(m) time. So is there any suggestion to solve this problem?


Solution

  • Explanation

    The key point of this problem is to ignore half part of A and B each step recursively by comparing the median of remaining A and B:

    if (aMid < bMid) Keep [aMid  +1 ... n] and [bLeft ... m]    
    else Keep [bMid + 1 ... m] and [aLeft ... n]
    // where n and m are the length of array A and B
    

    As the following: time complexity is O(log(m + n))

    public double findMedianSortedArrays(int[] A, int[] B) {
        int m = A.length, n = B.length;
        int l = (m + n + 1) / 2;
        int r = (m + n + 2) / 2;
        return (getkth(A, 0, B, 0, l) + getkth(A, 0, B, 0, r)) / 2.0;
    }
    
    public double getkth(int[] A, int aStart, int[] B, int bStart, int k) {
        if (aStart > A.length - 1) return B[bStart + k - 1];            
        if (bStart > B.length - 1) return A[aStart + k - 1];                
        if (k == 1) return Math.min(A[aStart], B[bStart]);
    
        int aMid = Integer.MAX_VALUE, bMid = Integer.MAX_VALUE;
        if (aStart + k/2 - 1 < A.length) aMid = A[aStart + k/2 - 1]; 
        if (bStart + k/2 - 1 < B.length) bMid = B[bStart + k/2 - 1];        
    
        if (aMid < bMid) 
            return getkth(A, aStart + k / 2, B, bStart, k - k / 2); // Check: aRight + bLeft 
        else 
            return getkth(A, aStart, B, bStart + k / 2, k - k / 2); // Check: bRight + aLeft
    }
    

    Hope it helps! Let me know if you need more explanation on any part.