【leetcode hot 100】【4】4. Find the median of two positive sequence arrays

topic

Given two positive order (from small to large) arrays nums1 and nums2 with sizes m and n respectively. Please find and return the median of these two ordinal arrays.
The time complexity of the algorithm should be O(log (m+n)).

Example 1:

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

Example 2:

Input: nums1 = [1,2], nums2 = [3,4]
Output: 2.50000
Explanation: Combined array = [1,2,3,4], median (2 + 3) / 2 = 2.5

hint:

  • nums1.length == m
  • nums2.length == n
  • 0 <= m <= 1000
  • 0 <= n <= 1000
  • 1 <= m + n <= 2000
  • -106 <= nums1[i], nums2[i] <= 106

problem solving ideas

This problem can be transformed into a problem of finding the Kth decimal of two sorted arrays, where K is half the total length of the two arrays. First compare the median of the two arrays, compare the K value with the subscript of the median, and determine the search range of the smaller array. Then perform a binary search in the smaller array, determine the subscript of the other array according to the subscript of the median, compare the values ​​at the corresponding positions of the two arrays, and adjust the search range of the smaller array according to the comparison result. Repeat the above steps until the Kth smallest number is found. Finally, the median is calculated according to the parity of K.

Time complexity: O(log(m+n)).

the code

c++

class Solution {
    
    
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
    
    
        int m = nums1.size(), n = nums2.size();
        // 确保 nums1 的长度小于等于 nums2,如果不是,则交换两个数组
        if (m > n) {
    
    
            return findMedianSortedArrays(nums2, nums1);
        }
        // 初始化 LMax1, LMax2, RMin1, RMin2, c1, c2, lo 和 hi
        int LMax1, LMax2, RMin1, RMin2, c1, c2, lo = 0, hi = 2 * m;
        // 二分查找
        while (lo <= hi) {
    
    
            // 计算 c1 和 c2
            c1 = (lo + hi) / 2;
            c2 = m + n - c1;
            // 计算 LMax1, LMax2, RMin1 和 RMin2
            LMax1 = (c1 == 0) ? INT_MIN : nums1[(c1 - 1) / 2];
            RMin1 = (c1 == 2 * m) ? INT_MAX : nums1[c1 / 2];
            LMax2 = (c2 == 0) ? INT_MIN : nums2[(c2 - 1) / 2];
            RMin2 = (c2 == 2 * n) ? INT_MAX : nums2[c2 / 2];
            // 如果 LMax1 大于 RMin2,则应该减小 c1,因为 nums1 部分太大了
            if (LMax1 > RMin2) {
    
    
                hi = c1 - 1;
            }
            // 如果 LMax2 大于 RMin1,则应该增大 c1,因为 nums1 部分太小了
            else if (LMax2 > RMin1) {
    
    
                lo = c1 + 1;
            }
            // 找到了合适的位置,结束循环
            else {
    
    
                break;
            }
        }
        // 返回中位数
        return (max(LMax1, LMax2) + min(RMin1, RMin2)) / 2.0;
    }
};

golang

package main

import "math"

func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {
    
    
    m, n := len(nums1), len(nums2)
    // 保证第一个数组较短,这样时间复杂度会更优
    if m > n {
    
    
        nums1, nums2, m, n = nums2, nums1, n, m
    }
    // lo 和 hi 分别表示在 nums1 中切割的位置
    lo, hi := 0, 2*m
    // 在 nums1 中切割位置为 c1,nums2 中切割位置为 c2
    for lo <= hi {
    
    
        c1 := (lo + hi) / 2
        c2 := m + n - c1
        var LMax1, RMin1, LMax2, RMin2 int
        // 计算 LMax1、RMin1、LMax2、RMin2
        if c1 == 0 {
    
    
            LMax1 = int(math.Inf(-1))
        } else if c1%2 == 1 {
    
    
            LMax1 = nums1[(c1-1)/2]
        } else {
    
    
            LMax1 = nums1[(c1-1)/2]
        }
        if c1 == 2*m {
    
    
            RMin1 = int(math.Inf(1))
        } else {
    
    
            RMin1 = nums1[c1/2]
        }
        if c2 == 0 {
    
    
            LMax2 = int(math.Inf(-1))
        } else if c2%2 == 1 {
    
    
            LMax2 = nums2[(c2-1)/2]
        } else {
    
    
            LMax2 = nums2[(c2-1)/2]
        }
        if c2 == 2*n {
    
    
            RMin2 = int(math.Inf(1))
        } else {
    
    
            RMin2 = nums2[c2/2]
        }
        // 如果 LMax1 大于 RMin2,则应该减小 c1,因为 nums1 部分太大了
        if LMax1 > RMin2 {
    
    
            hi = c1 - 1
        }
        // 如果 LMax2 大于 RMin1,则应该增大 c1,因为 nums1 部分太小了
        if LMax2 > RMin1 {
    
    
            lo = c1 + 1
        }
        // 找到了合适的位置,结束循环
        if LMax1 <= RMin2 && LMax2 <= RMin1 {
    
    
            break
        }
    }
    // 返回中位数
    return float64((math.Max(float64(LMax1), float64(LMax2)) + math.Min(float64(RMin1), float64(RMin2))) / 2.0)
}

Guess you like

Origin blog.csdn.net/weixin_41093846/article/details/129944828