Leetcode-4 Median of Two Sorted Arrays (java)

Keywords: Java

Median of Two Sorted Arrays

subject

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

Example 1:

nums1 = [1, 3]
nums2 = [2]

The median is 2.0
Example 2:

nums1 = [1, 2]
nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5

translate

Arrays nums1 and nums2 with two sorts and length m and n, respectively. Find the middle value of the two sorts.
The required running time is O(log(m+n))

Example 1:

nums1 = [1, 3]
nums2 = [2]

Median value: 2.0
Example 2:

nums1 = [1, 2]
nums2 = [3, 4]

Median value: (2 + 3) / 2 = 2.5

Solutions

After merging two arrays, if they are odd, return the middle value. If they are even, return the average value of the middle two numbers

  • Solution of merger

    The principle of merging is to merge two arrays and calculate the median value. Its running time is O((m+n)/2)
    But it can not meet the requirement of running time.

  • Recursive solution

    This approach was found in the discussion area. The principle of implementation: find the k(k = (m+n) / 2 + 1) smallest number in the array
    When comparing nums1[k] with nums2[k], there are three situations:
    If nums1[k] == nums2[k], then this value is the value to be found.
    If nums1 [k] < nums2 [k], then the k-th value must appear in the interval of nums1 [(K + 1) ~ M] and nums2 [0 ~ (k-1)]
    If nums1 [k] > nums2 [k], then the k-th value must appear in nums1 [0 ~ (k-1)] and nums2 [(K + 1) ~ n] intervals

Code example java

package com.yumo.java.airthmetic.leetcode;

/**
 * Created by yumodev on 8/7/16.
 */
public class MedianTwoSortedArrays_4 {

    /**
     * String processing by merging
     */
    public static double findMedianSortedArraysByMerge(int[] nums1, int[] nums2) {
        if (nums1.length == 0 && nums2.length == 0) return 0;
        int leftMedian = (nums1.length+nums2.length+1)/2;
        int rightMedian = (nums1.length+nums2.length+2)/2;
        if (nums1.length == 0){
            return (nums2[leftMedian - 1]+ nums2[rightMedian - 1]) / 2.0;
        }else if(nums2.length == 0){
            return (nums1[leftMedian - 1]+ nums1[rightMedian - 1]) / 2.0;
        }

        int num = 0, firstNum = 0;
        int n1 = 0, n2 = 0, index = 1;
        while (true){
            if (n1 < nums1.length){
                if (n2 < nums2.length){
                    if(nums1[n1] > nums2[n2]){
                        num = nums2[n2++];
                    }else{
                        num = nums1[n1++];
                    }
                }else{
                    num = nums1[n1++];
                }
            }else{
                num = nums2[n2++];
            }

            if (index == leftMedian && rightMedian == leftMedian){
                return num;
            }else if (index == leftMedian && rightMedian != leftMedian){
                firstNum = num;
            }else if (index == rightMedian){
                return (firstNum + num)/2.0;
            }

            index++;
        }
    }

    /**
     * Implemented recursively
     * @param nums1
     * @param nums2
     * @return
     */
    public static double findMedianSortedArraysByRecursive(int[] nums1, int[] nums2) {
        if (nums1.length == 0 && nums2.length == 0) return 0;
        int leftMedian = (nums1.length+nums2.length+1)/2;
        int rightMedian = (nums1.length+nums2.length+2)/2;

        if (nums1.length == 0){
            return (nums2[leftMedian - 1]+ nums2[rightMedian - 1]) / 2.0;
        }else if(nums2.length == 0){
            return (nums1[leftMedian - 1]+ nums1[rightMedian - 1]) / 2.0;
        }

        if (rightMedian != leftMedian){
            return (getMedianNum(nums1,0,nums2,0,leftMedian)+ getMedianNum(nums1,0,nums2,0,rightMedian))/2.0;
        }else{
            return getMedianNum(nums1,0,nums2,0,leftMedian);
        }
    }

    public static double getMedianNum(int[] nums1, int start1, int[]nums2, int start2, int index){
        if(start1 > nums1.length-1) return nums2[start2+index-1];
        if(start2 > nums2.length-1) return nums1[start1+index-1];
        if(index == 1) return Math.min(nums1[start1],nums2[start2]);

        if(start2+index/2-1 > nums2.length-1){
            return getMedianNum(nums1,start1+index/2,nums2,start2,index-index/2);
        } 
        if(start1+index/2-1 > nums1.length-1){
            return getMedianNum(nums1,start1,nums2,start2+index/2,index-index/2);
        } 

        if(nums1[start1+index/2-1] < nums2[start2+index/2-1]){
            return getMedianNum(nums1,start1+index/2,nums2,start2,index-index/2);
        }else{
            return getMedianNum(nums1,start1,nums2,start2+index/2,index-index/2);
        }
    }

    public static void main(String[] args){
        int[] nums1 = {1,3};
        int[] nums2 = {2};

//        int[] nums1 = {1,3};
//        int[] nums2 = {2};
        long startTime = System.nanoTime();
        double median = findMedianSortedArraysByMerge(nums1, nums2);
        long endTime = System.nanoTime();
        long time = endTime - startTime;
        System.out.println(" median:"+median +" time:"+ time);
        
        startTime = System.nanoTime();
        median = findMedianSortedArraysByRecursive(nums1, nums2);
        endTime = System.nanoTime();
        time = endTime - startTime;
        System.out.println(" median:"+median +" time:"+ time);
    }
}

Posted by NoReason on Wed, 13 Nov 2019 11:32:34 -0800