0004. Median of Two Sorted Arrays

https://leetcode.com/problems/median-of-two-sorted-arrays

Description

Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays.

The overall run time complexity should be O(log (m+n)).

Example 1:

**Input:** nums1 = [1,3], nums2 = [2]
**Output:** 2.00000
**Explanation:** merged array = [1,2,3] and median is 2.

Example 2:

**Input:** nums1 = [1,2], nums2 = [3,4]
**Output:** 2.50000
**Explanation:** merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5.

Example 3:

**Input:** nums1 = [0,0], nums2 = [0,0]
**Output:** 0.00000

Example 4:

**Input:** nums1 = [], nums2 = [1]
**Output:** 1.00000

Example 5:

**Input:** nums1 = [2], nums2 = []
**Output:** 2.00000

Constraints:

  • nums1.length == m

  • nums2.length == n

  • 0 <= m <= 1000

  • 0 <= n <= 1000

  • 1 <= m + n <= 2000

  • -106 <= nums1[i], nums2[i] <= 106

ac1: iterative

// iterative version, very ugly and tedious
class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        // findKth, k=(m+n)/2
        // M[k/2], N[k/2].  deduct k/2 each time. untill k == 1
        // if M[k/2] < N[k/2], 'delete' <-[k/2]
        // if (m+n) % 2 == 0, (M[0]+N[0]) / 2, else M[0]

        // corner cases
        if (nums1.length == 0 && nums2.length == 0) return 0;

        return findKth(nums1, nums2, 0, 0);
    }

    private double findKth(int[] nums1, int[] nums2, int s1, int s2) {
        int k = (nums1.length + nums2.length + 1) / 2; // kth number 

        while (k > 1 && s1 < nums1.length && s2 < nums2.length) {
            int mid1 = s1+k/2-1 < nums1.length ? nums1[s1+k/2-1] : Integer.MAX_VALUE;
            int mid2 = s2+k/2-1 < nums2.length ? nums2[s2+k/2-1] : Integer.MAX_VALUE;
            if (mid1 < mid2) s1 += k/2;
            else s2 += k/2;
            k = k - k/2;
        }

        // get mid points
        int first = 0, second = 0;
        if (s1 >= nums1.length) {
            first = nums2[s2+k-1];
            if (s2+k < nums2.length) second = nums2[s2+k];
        } else if (s2 >= nums2.length) {
            first = nums1[s1+k-1];
            if (s1+k < nums1.length)second = nums1[s1+k];
        } else {
            first = nums1[s1] < nums2[s2] ? nums1[s1++] : nums2[s2++];
            if (s1 >= nums1.length) second = nums2[s2];
            else if (s2 >= nums2.length) second  = nums1[s1];
            else second = Math.min(nums1[s1],nums2[s2]);
        }

        // return result
        if ((nums1.length + nums2.length) % 2 != 0) {
            return (double) first;
        } else {
            return (double) (first+second) / 2;
        }
    }
}

Last updated