【码道初阶】进阶必看!双重二分查找+边界处理:Leetcode.4寻找两个正序数组的中位数,细节很多的Hard题

问题回顾

给定两个大小分别为 mn 的正序(从小到大)数组 nums1nums2。请你找出并返回这两个正序数组的 中位数 。

算法的时间复杂度应该为 O(log (m+n))

示例 1:

输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:

输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5

提示:

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


步骤一:问题分析与直觉

目标:找到两个有序数组合并后的中位数,要求时间复杂度为O(log(m + n))。

关键观察

  1. 中位数定义:将合并后的数组分为左右两部分,左边所有元素 ≤ 右边所有元素,且左半部分长度与右半部分相等或大1。
  2. 分割点性质:若找到分割点使得左半部分的最大值 ≤ 右半部分的最小值,则中位数由这两个值决定。

步骤二:算法设计

1. 确保较短的数组进行二分查找
  • 交换数组,使nums1是较短的数组。这可以优化时间复杂度至O(log(min(m, n)))。
2. 确定分割点
  • 定义inums1的分割点,jnums2的分割点,满足:
    i + j = (m + n + 1) / 2
    
  • 左半部分包含nums1[0..i-1]nums2[0..j-1],右半部分包含nums1[i..m-1]nums2[j..n-1]
3. 边界条件处理
  • i=0nums1的左半部分为空 → nums1LeftMax = INT_MIN
  • i=mnums1的右半部分为空 → nums1RightMin = INT_MAX
  • j=0nums2的左半部分为空 → nums2LeftMax = INT_MIN
  • j=nnums2的右半部分为空 → nums2RightMin = INT_MAX
4. 调整分割点的条件
  • 正确分割的条件
    nums1LeftMax ≤ nums2RightMin 且 nums2LeftMax ≤ nums1RightMin
    
  • 条件不满足时的调整
    • nums1LeftMax > nums2RightMin:说明i太大,需减小 → high = i - 1
    • nums2LeftMax > nums1RightMin:说明i太小,需增大 → low = i + 1
5. 计算中位数
  • 总长度为奇数:中位数为左半部分的最大值max(nums1LeftMax, nums2LeftMax)
  • 总长度为偶数:中位数为(max(nums1LeftMax, nums2LeftMax) + min(nums1RightMin, nums2RightMin)) / 2.0

步骤三:代码实现与注释

class Solution {
   
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
   
    if(nums1.size()>nums2.size())//这里始终保证nums1是更小的数组 避免接下来数组越界。
    {
   
        return findMedianSortedArrays(nums2,nums1);
    }
    int m = nums1.size(),n = nums2.size(),totalleft = (m+n+1)/2; //左半部分总元素数 数组元素数量为奇数的时候就是中间数
    int low = 0,high=m;
    while(low<=high)
    {
   
        int i = 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值