寻找两个正序数组的中位数从暴力到优化

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

示例 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

示例 3:

输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000

示例 4:

输入:nums1 = [], nums2 = [1]
输出:1.00000

示例 5:

输入:nums1 = [2], nums2 = []
输出:2.00000

提示:

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

暴力求解(算法复杂度(m+n)/2)稳定

double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int i=(nums1.size()+nums2.size())%2;
        int m=(nums1.size()+nums2.size())/2;
        vector<int>t;
        int x=0,y=0;
        for(int j=0;j<m+1;j++)
        {
            if(x>=nums1.size())
            {
                t.push_back(nums2[y]);
                y++;
            }
            else if(y>=nums2.size())
            {
                t.push_back(nums1[x]);
                x++;
            }
            else if(nums1[x]>nums2[y])
            {
                t.push_back(nums2[y]);
                y++;
            }
            else
            {
                t.push_back(nums1[x]);
                x++;
            }
        }
       if(i)
       {
            return t[t.size()-1];
       }
       else{
           return ((t[t.size()-1]+t[t.size()-2])*1.0/2);
       }
    }

使用二分法查找

在这里插入图片描述

#include <stdio.h>
#include <vector>
using namespace std;

#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))

class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size();
        int m = nums2.size();

        if (n > m)  //保证数组1一定最短
        {
                return findMedianSortedArrays(nums2, nums1);
        }

// Ci 为第i个数组的割,比如C1为2时表示第1个数组只有2个元素。LMaxi为第i个数组割后的左元素。RMini为第i个数组割后的右元素
        int LMax1, LMax2, RMin1, RMin2, c1, c2, lo = 0, hi = 2 * n;  //我们目前是虚拟加了'#'所以数组1是2*n长度

        while (lo <= hi)   //二分
        {
                c1 = (lo + hi) / 2;  //c1是二分的结果
                c2 = m + n - c1;
 
            LMax1 = (c1 == 0) ? INT_MIN : nums1[(c1 - 1) / 2];
                RMin1 = (c1 == 2 * n) ? INT_MAX : nums1[c1 / 2];
                LMax2 = (c2 == 0) ? INT_MIN : nums2[(c2 - 1) / 2];
                RMin2 = (c2 == 2 * m) ? INT_MAX : nums2[c2 / 2];

            if (LMax1 > RMin2)
                    hi = c1 - 1;
                else if (LMax2 > RMin1)
                        lo = c1 + 1;
                else
                        break;
        }
        
        return (max(LMax1, LMax2) + min(RMin1, RMin2)) / 2.0;
        }
};


int main(int argc, char *argv[])
{
vector<int> nums1 = { 2,3, 5 };
vector<int> nums2 = { 1,4,7, 9 };

Solution solution;
double ret = solution.findMedianSortedArrays(nums1, nums2);
return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值