leetcode finds the median hard of two sorted arrays

topic link

This article is very comprehensive: https://www.cnblogs.com/grandyang/p/4465932.html

 

The excerpt is as follows:

 

This question asks us to find the median of two ordered arrays, and limits the time complexity to O(log (m+n)). Seeing this time complexity, we naturally think that we should use the binary search method to Solve. But there is a reason why this problem is defined as Hard. The difficulty is to use dichotomy between two unmerged sorted arrays. If this problem has only one sorted array, let's find the median If so, it is estimated to be an Easy question. So can we mix two ordered arrays into one ordered array and do it again? The pattern is broken. The time complexity limit is to tell you to stop thinking about it. Then we still use the dichotomy method, and it is used between two arrays, which feels very high-end. Then review the definition of median. If the length of an ordered array is odd, then the median is the middle one, and if it is even, then it is the average of the two middlemost numbers. The same is true for two ordered arrays here. Assuming that the lengths of the two ordered arrays are m and n, respectively, since the parity of the sum of the lengths of the two arrays m+n is uncertain, it needs to be discussed separately. In this case, you can directly find the middle number. If there is an even number, you need to find the average of the middle two numbers. In order to simplify the code, regardless of the situation, we use a small trick, we find the (m+n+1) / 2th and (m+n+2) / 2th respectively, and then find the average value, This works for odd and even numbers. If m+n is an odd number, then (m+n+1) / 2 and (m+n+2) / 2 are actually equal, which is equivalent to adding two identical numbers and dividing by 2, or itself .

Well, here we need to define a function to find the Kth element in two sorted arrays. Let's focus on how to find the Kth element. First, in order to avoid generating a new array and increasing the time complexity, we use two variables i and j to mark the starting positions of the arrays nums1 and nums2 respectively. Then deal with some corner cases. For example, when the starting position of an array is greater than or equal to its array length, it means that all its numbers have been eliminated, which is equivalent to an empty array, then it actually becomes another Find numbers in the array, you can find them directly. Also, if K=1, then we only need to compare the numbers at the starting positions i and j of nums1 and nums2. The difficulty lies in how to deal with the general situation? Because we need to find the Kth element in two sorted arrays, in order to speed up the search, we're going to use the bisection method, so who to dichotomize, the array? In fact, we need to divide K into two, which means that we need to find the K/2th element in nums1 and nums2 respectively. Note that because the lengths of the two arrays are uncertain, it is possible that an array does not have the K/2th number, so we You need to check first whether the K/2th number exists in the array. If it exists, take it out, otherwise, assign an integer maximum value. If an array does not have the K/2th number, then we just eliminate the first K/2 numbers of the other number. Is it possible that the K/2th number does not exist in both arrays? It is impossible in this question, because our K is not given arbitrarily, but the middle value of m+n given, so it must be at least There is an array where the K/2th number exists. Finally, the core of the dichotomy method is to compare the sizes of midVal1 and midVal2 of the K/2th smallest numbers of these two arrays. If the K/2th number of the first array is small, it means that the number we are looking for must be The first K/2 numbers that are not in nums1, so we can knock them out, move the starting position of nums1 backward by K/2, and K/2 is also subtracted from K at this time, calling recursion. On the contrary, we eliminate the first K/2 numbers in nums2, and move the starting position of nums2 backward by K/2, and K/2 is also subtracted from K at this time, just call recursion, see the code as follows :

 

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int m = nums1.length, n = nums2.length;
        int l = (m + n + 1) / 2, r = (m + n + 2) / 2;
        return (findKth(nums1, 0, nums2, 0, l) + findKth(nums1, 0, nums2, 0, r)) / 2.0;
        
    }
    int findKth(int[] nums1, int i, int[] nums2, int j, int k) {
        if(i >= nums1.length) return nums2[j + k - 1];
        if(j >= nums2.length) return nums1[i + k - 1];
        if(k == 1) return Math.min(nums1[i], nums2[j]);
        int x1 = (i + k / 2 - 1 < nums1.length) ? nums1[i + k / 2 - 1] : Integer.MAX_VALUE;
        int x2 = (j + k / 2 - 1 < nums2.length) ? nums2[j + k / 2 - 1] : Integer.MAX_VALUE;
        if(x1 < x2) {
            return findKth(nums1, i + k / 2, nums2, j, k - k / 2);
        }
        else return findKth(nums1, i, nums2, j + k / 2, k - k / 2);
    }
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326546516&siteId=291194637