4. Median of Two Sorted Arrays

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

The main idea of ​​the title: Given two ascending arrays, ask for the median of the two arrays (the number in the middle, if the total is odd, it is the middle number, if it is even, it is the average of the middle two numbers).
Problem-solving idea 1: brute force method, insert two arrays in order, arrange a new array, insert by value, complexity O(m+n), and then directly find the median of the new array.
Code 1 (violence):

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int s1 = nums1.size();
        int s2 = nums2.size();
        int s3 = s1 + s2;
        vector<int> nums3(s3);
        double res = 0.0;
        for (int i = 0, j = 0, k = 0; i <= s1 && j <= s2 && k < s3; k++) {
            if (i == s1 && j < s2) {
                nums3[k] = nums2[j];
                j++;
                continue;
            } else if (j == s2 && i < s1) {
                nums3[k] = nums1[i];
                i++;
                continue;
            }
            if (nums1[i] <= nums2[j]) {
                nums3[k] = nums1[i];
                i++;
            } else if (nums1[i] > nums2[j]) {
                nums3[k] = nums2[j];
                j++;
            }
        }
        if (s3 % 2) {
            res = nums3[s3 / 2];
        } else {
            res = (double)(nums3[s3 / 2 - 1] + nums3[s3 / 2]) / 2;
        }
        return res;
    }
};

Idea 2: Dichotomy. For a detailed analysis, see
https://leetcode.com/problems/median-of-two-sorted-arrays/solution/
Mainly based on this conclusion:
write picture description here
explain the first article, why j=0,i=m和B[j-1]<=A[i]it is equivalent:
j=0, indicating the left of B The length is 0, so there must be the maximum value of the left part of B <= the minimum value of the right of A;
i=m, indicating that the length of the right of A is 0, so there must be the maximum value of the left part of A <= the minimum value of the right of B Value;
B[j-1]<=A[i], this needs no explanation, that is, the largest in the left of B <= the smallest in the right of A.
The same i=0,j=n和A[i-1]<=B[j]is true for the analysis.
Both conditions must be met.

In addition, why j = (m+n+1)/2 - i?
Because in the analysis, A and B are divided into two equal sections.
At this time i+j=m-i+n-j, that is,j=(m+n)/2-i

      left_part          |        right_part
A[0], A[1], ..., A[i-1]  |  A[i], A[i+1], ..., A[m-1]
B[0], B[1], ..., B[j-1]  |  B[j], B[j+1], ..., B[n-1]

However, the left and right segments are not necessarily equal (when m+n is an odd number): i+j=m-i+n-j+1, that is, j=(m+n+1)/2-i
since j is an int type, even if m+n is an even number, dividing +1 by 2 is still the original result, so m+ The odd and even cases of n are unified:
j = (m+n+1)/2 - i

Code 2 (two points):

class Solution {
public:
    double findMedianSortedArrays(vector<int>& A, vector<int>& B) {
        int m = A.size();
        int n = B.size();
        //有一个数组为空,直接求另一个的中位数
        if (m == 0) return n%2 ? B[n/2] : (B[n/2-1] + B[n/2]) / 2.0;
        if (n == 0) return m%2 ? A[m/2] : (A[m/2-1] + A[m/2]) / 2.0;
        if (m > n) {  //保证m<=n
            vector<int> temp = A, A = B, B = temp;
            int tmp = m, m = n, n = tmp;
        }
        int iMin = 0, iMax = m;
        while (iMin <= iMax) {
            int i = (iMin + iMax) / 2;
            int j = (m + n + 1) / 2 - i;
            if (j > 0 && i < m && B[j-1] > A[i]) {
                iMin++;
            } else if (i > 0 && j < n && A[i-1] > B[j]) {
                iMax--;
            } else {
                int leftMax = 0;
                if (i == 0) leftMax = B[j-1];
                else if (j == 0) leftMax = A[i-1];
                else leftMax = max(A[i-1], B[j-1]);
                if ((m + n) % 2 == 1) return leftMax;

                int rightMin = 0;
                if (i == m) rightMin = B[j];
                else if (j == n) rightMin = A[i];
                else rightMin = min(A[i], B[j]);

                return (leftMax + rightMin) / 2.0;
            }
        }
    }
};

Guess you like

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