Find the median of two ordered arrays

Keywords: C++ less

If we use the algorithm with time complexity O (m+n), it will be very simple. Today we will introduce an algorithm with time complexity O (log(m+n)).

Here we use the idea of dichotomy to solve this problem. First, the array we give is two ordered arrays. In this way, we can easily divide the two arrays into two parts, and the median we are looking for only needs to divide the combined array into two parts of equal length, and the maximum value on the left is less than the minimum value on the right. Then we can first satisfy the first condition, and then we can find the way to divide the two arrays into two parts. Then we can easily give the median value. The program code is as follows:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2);
int main()
{
    int len_1, len_2;
    cin >> len_1 >> len_2;
    vector<int> nums1(len_1);
    vector<int> nums2(len_2);
    for (int i = 0; i < len_1; ++i)
    {
        cin >> nums1[i];
    }
    for (int i = 0; i < len_2; ++i)
    {
        cin >> nums2[i];
    }
    cout << findMedianSortedArrays(nums1, nums2);
    return 0;
}

double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) 
{
    int m = nums1.size();
    int n = nums2.size();
    vector<int> temps1;
    vector<int> temps2;
    if (m > n)
    {
        temps1 = nums2;
        temps2 = nums1;
        int tmp = m; m = n; n = tmp;
    }
    else
    {
        temps1 = nums1;
        temps2 = nums2;
    }
    int iMin = 0, iMax = m, halflen = (m + n + 1) / 2;
    //The above steps ensure that array 1 is shorter than array 2, so that any division in array 1 is valid in array 2.
    while (iMin <= iMax)
    {
        int i = (iMin + iMax) / 2;
        int j = halflen - i;//because m<=n,therefore j It can be directly assigned as halflen - i
        if (i < iMax && temps2[j - 1] > temps1[i]) 
        {
            iMin = i + 1; // i is too small
        }
        else if (i > iMin && temps1[i - 1] > temps2[j]) 
        {
            iMax = i - 1; // i is too big
        }
        //The above steps are the key codes to realize dichotomy, and each dichotomy is to find the right code i Value.
        else 
        { // i is perfect
            double maxLeft = 0;

            if (i == 0) 
            { 
                maxLeft = temps2[j - 1]; 
                //nums1 There is no element in the left part, so the biggest one on the left is nums2 The last element of the left part of
            }
            else if (j == 0) 
            { 
                maxLeft = temps1[i - 1]; 
                //nums2 There is no element in the left part, so the biggest one on the left is nums1 The last element of the left part of
            }
            else 
            { 
                maxLeft = max(temps1[i - 1], temps2[j - 1]); 
                //nums1 The left part and nums2 There are elements in the left part, take the maximum value
            }
            if ((m + n) % 2 == 1) 
            { 
                return maxLeft; 
                //If it is an odd number, it will return the value directly
            }

            double minRight = 0;

            if (i == m) 
            { 
                minRight = temps2[j]; 
            }
            else if (j == n) 
            { 
                minRight = temps1[i]; 
            }
            else 
            { 
                minRight = min(temps2[j], temps1[i]); 
            }

            return (maxLeft + minRight) / 2;
            //If it's even, take the sum of two numbers and divide by two
        }
    }
    return 0;
}

Posted by jaymoore_299 on Thu, 09 Apr 2020 07:38:09 -0700