4. Median(Kth element) of Two Sorted Arrays

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

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

Solution

Two Pointer approach

Intuitive, it can be done by two pointers approach.

Iterate the element from the two element till find the kth element or Math.abs(n+m/2)th elements

-> Time complexitiy : O(N)

But, it is not the optimal solution, the optional solution is O(log N) or O(logM), N and M are the length of nums1 and nums2

Binary Search Approach (Important)

Idea: When thinking about a sorted array and time complexity is required to be O(logN), we shall think of the feasibility of a binary search approach.

Let's see the relationship between a kth element and the two arrays.

If M is the kth element among Arrays A, B, it shall satisfy:

  1. elementA[0]....A[i] B[0]...B[j] all less or equal to M, and i -1 + j = k

And we know that the kth element must appear among A[0] ... A[k/2-1] and B[0].... B[k/2-1]

So, we can start to compare the medium value (lets Call them Am and Bm) to narrow down the searching intervals:

  • Am > Bm :

    • it means the left half of B is not possible to be the kth element, those elements on the left side of B shall all be on the left side of the kth element. So next round, we will search from m+1 of B and also decrease the searching kth to (k-2/k)th, since 2/k elements are already found, we need to find from rest of them

  • Am <= Bm

    • It means the left half of A is not possible to be the kth element, they shall be ont the left side of kth element ... so on so forth.

Once the k is equal to 1, the min of A[start] and B[start] will be the anwser

If one of the mid-index is over the size of its array, it means we shall continue the search the same interval in the next round, only narrow down another one.

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int m = nums1.length;
        int n = nums2.length;
        if((n+m)%2 == 0){
            int left = findKthValue(nums1, 0, nums2, 0, (n+m)/2);
            int right = findKthValue(nums1, 0, nums2, 0, (n+m)/2 + 1);
            System.out.print(left+" + " + right);
            return ((double)(left + right))/2.0;
        }else{
            return findKthValue(nums1, 0, nums2, 0, (n+m)/2 + 1);
        }
    }
    
    //to find the kth value of a merged array which is merged from num1[start1:] and num2[start2:]
    public int findKthValue(int[] nums1, int start1, int[] nums2, int start2, int k){
        if(start1 >= nums1.length){
            return nums2[start2+k-1];
        }
        
        if(start2 >= nums2.length){
            return nums1[start1+k-1];
        }
        
        if(k == 1){
            return Math.min(nums1[start1], nums2[start2]);
        }
        
        
        int mid1 = start1 + (k/2) - 1;
        int mid2 = start2 + (k/2) - 1 ;
        int val1 = (mid1 >= nums1.length)? Integer.MAX_VALUE : nums1[mid1];
        int val2 = (mid2 >= nums2.length)? Integer.MAX_VALUE : nums2[mid2];
        if(val1 > val2){
            return findKthValue(nums1, start1, nums2, mid2+1, k - k/2);
        }else{
            return findKthValue(nums1, mid1+1, nums2, start2, k - k/2);
        }
    }
    
}

Last updated

Was this helpful?