Leetcode::Median of Two Sorted Arrays

point

Design

Approach 2

Approach 3

Big O(time)

Code

Approach 2 : O(log(n x m ))

class Solution {
public:
    int bs(vector<int> A, vector<int> B, int k, int aStart, int aEnd, int bStart, int bEnd) {
        // [ section A ] [ section B ]
        //                   ^
        //                   k
        // aStart is the last index of A (= A.size() - 1). x is the point of k in B
        // k = aStart + x -> x = k - aStart
        if (aStart > aEnd) {
            return B[k - aStart];
        }

        // [ section B ] [ section A ]
        if (bStart > bEnd) {
            return A[k - bStart];
        }

        int aMid = (aStart + aEnd) / 2, bMid = (bStart + bEnd) / 2;
        int aMidV = A[aMid], bMidV = B[bMid];

        if (aMid + bMid < k) {
            // aMid < k -> no need of left side of A
            if (aMidV <= bMidV) {
                return bs(A, B, k, aMid + 1, aEnd, bStart, bEnd);
            }
            // bMid < k -> no need of left side of B
            else {
                return bs(A, B, k, aStart, aEnd, bMid + 1, bEnd);
            }
        }
        // aMid + bMid >= k
        else {
            // no chance of having k'th on B_right side
            if (aMidV <= bMidV) {
                return bs(A, B, k, aStart, aEnd, bStart, bMid - 1);
            }
            // no chance of having k'th on A_right side
            else {
                return bs(A, B, k, aStart, aMid - 1, bStart, bEnd);
            }
        }
    }
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int n1 = nums1.size(), n2 = nums2.size();
        int n = n1 + n2;
        
        if (n % 2 == 1) {
            return bs(nums1, nums2, n/2, 0, n1 - 1, 0, n2 - 1);
        }
        else {
            return (double)(bs(nums1, nums2, n/2, 0, n1 - 1, 0, n2 - 1) + bs(nums1, nums2, n/2 - 1, 0, n1 - 1, 0, n2 - 1)) / 2;
        }
    }
};

Approach 3 : O(log(min(n, m)))

class Solution {
public:
    double findMedianSortedArrays(vector<int>& A, vector<int>& B) {
        int m = A.size(), n = B.size();
        if (m > n) return findMedianSortedArrays(B, A);

        int left = 0, right = m;
        while(left <= right) {
            int partionA = (left + right) / 2;
            int partionB = (n + m + 1) / 2 - partionA;

            int maxLeftA  = (partionA == 0 ? -1e7 : A[partionA - 1]);
            int minRightA = (partionA == m ? +1e7 : A[partionA]);
            int maxLeftB  = (partionB == 0 ? -1e7 : B[partionB - 1]);
            int minRightB = (partionB == n ? +1e7 : B[partionB]);

            if (maxLeftA <= minRightB && maxLeftB <= minRightA) {
                if ((n + m) % 2 == 0) {
                    return (double)(max(maxLeftA, maxLeftB) + min(minRightA, minRightB)) / 2.0;
                } else {
                    return max(maxLeftA, maxLeftB);
                }
            }
            else if (maxLeftA > minRightB) {
                right = partionA - 1;
            }
            else if (maxLeftB > minRightA) {
                left = partionA + 1;
            }
            else {
                // nothing can get here
                exit(1);
            }
        }
        return 0.0;
    }
};