Force deduction question 4 find the median of two positive arrays

Keywords: Java leetcode

Give two positively ordered (from small to large) arrays of sizes m and n   nums1 and   nums2. Please find and return the median of these two positive arrays.

Example 1:

Input: nums1 = [1,3], nums2 = [2]
Output: 2.00000
Explanation: merge array = [1,2,3], median 2

Example 2:

Input: nums1 = [1,2], nums2 = [3,4]
Output: 2.50000
Explanation: merged array = [1,2,3,4], median (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

1. Own solution: make middle=(length1+length2)/2. To find the median, you need to divide it into two cases: the total number of array elements is odd and even. If it is an odd number, the median is the largest number in the middle; If it is an even number, the median is the average of the sum of the number with the largest middle and the number with the largest middle+1. That is, the problem finally becomes to find the number with the largest middle and the largest middle+1 in the two arrays, so write a function to find the number with the largest K.

    Find the K / 2nd number in two arrays A and B, namely A[K/2-1] and B[K/2-1]. At this time, compare the size of these two numbers in three cases:

        ① A [K/2-1] < B [K/2-1], then it indicates that the first K/2 elements in a cannot be the k-th number. Exclude these numbers,

          Continue to look in the remaining elements.

        ②A[K/2-1] >   B[K/2-1], then it means that the first k / 2 elements in B cannot be the k-th number. Exclude these numbers,

          Continue to look in the remaining elements.

        ③A[K/2-1] =   B[K/2-1], which can be classified into the first case.

    You can use recursion. Pay attention to the update of K after excluding elements every time, and the update of the new starting subscript of the two arrays should be very detailed. Also note that the K-th largest subscript is K-1. Recursion can also be changed to a loop.

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int length1 = nums1.length;
        int length2 = nums2.length;
        int totalLength = length1 + length2;
        int middleIndex = (length1 + length2)/2;

        if(totalLength % 2 == 1){//Cases where the total number is odd
            return getKthNumber(nums1,nums2,middleIndex + 1,0,0);
        }else{//Cases where the total number is even
            return (double)(getKthNumber(nums1,nums2,middleIndex,0,0) + getKthNumber(nums1,nums2,middleIndex + 1,0,0)) / 2;
        }
    }
    //Find the k-th largest number in two arrays
    public int getKthNumber(int[] nums1,int[] nums2,int k,int index1,int index2){
        int length1 = nums1.length;
        int length2 = nums2.length;

        //Boundary condition
        if(index1 == length1){//When the first array has no remaining elements
            return nums2[index2 + k - 1];
        }
        if(index2 == length2){//When the second array has no remaining elements
            return nums1[index1 + k - 1];
        }
        if(k == 1){//When k is equal to 1, you can directly compare the first of the remaining elements of the two arrays
            return Math.min(nums1[index1],nums2[index2]);
        }

        //Other normal conditions
        int half = k/2;
        int newIndex1 = Math.min(length1,half + index1) - 1;//Determine whether the array subscript will be out of bounds
        int newIndex2 = Math.min(length2,half + index2) - 1;
        if(nums1[newIndex1] <= nums2[newIndex2]){
            return getKthNumber(nums1,nums2,k - (newIndex1 - index1 + 1),newIndex1 + 1,index2);//Update the remaining k and the new array start subscript
        }else{
            return getKthNumber(nums1,nums2,k - (newIndex2 - index2 + 1),index1,newIndex2 + 1);
        }

    }
}

2. Other solutions. See a person using a small skill, here also post it (from the comment @ Wait). We can find the (m+n+1) / 2 and (m+n+2) / 2 respectively, and then find their average value, which is applicable to odd and even numbers. If m+n is an odd number, then the values of (m+n+1) / 2 and (m+n+2) / 2 are equal, which is equivalent to adding two identical numbers and dividing them by 2, or itself.

    His code and its brevity:

class Solution {
  public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int m = nums1.length;
        int n = nums2.length;
        int left = (m + n + 1) / 2;
        int right = (m + n + 2) / 2;
        return (findKth(nums1, 0, nums2, 0, left) + findKth(nums1, 0, nums2, 0, right)) / 2.0;
    }
    //i: Start position of nums1 J: start position of nums2
    public int findKth(int[] nums1, int i, int[] nums2, int j, int k){
        if( i >= nums1.length) return nums2[j + k - 1];//nums1 is an empty array
        if( j >= nums2.length) return nums1[i + k - 1];//nums2 is an empty array
        if(k == 1){
            return Math.min(nums1[i], nums2[j]);
        }
        int midVal1 = (i + k / 2 - 1 < nums1.length) ? nums1[i + k / 2 - 1] : Integer.MAX_VALUE;
        int midVal2 = (j + k / 2 - 1 < nums2.length) ? nums2[j + k / 2 - 1] : Integer.MAX_VALUE;
        if(midVal1 < midVal2){
            return findKth(nums1, i + k / 2, nums2, j , k - k / 2);
        }else{
            return findKth(nums1, i, nums2, j + k / 2 , k - k / 2);
        }        
    }
}

    It is mainly to learn the skills of not distinguishing parity.

Question source: Force buckle

Posted by joecrack on Tue, 21 Sep 2021 19:01:40 -0700