求两个有序数组的中位数

这篇博客探讨了如何在两个已排序的数组中找到中位数。直接遍历法通过找到第n和第n-1个元素的平均值实现,时间复杂度为O(n)。分治法通过寻找两个数组的中位数m1和m2,以O(log(m+n))的时间复杂度解决该问题。
摘要由CSDN通过智能技术生成
问题描述

有两个排序的数组,长度都为n,求合并后的排序数组的中位数.

直接遍历法,时间复杂度为O(n)

算法思想: 因为两个数组的长度都为n,那么合并后的中位数一定有两个,那么,我们只要在两个数组合并后的数组中找到找到第n个和第n-1个元素加起来除2就能得到其中位数。 (当然,我们不会真正的去合并两个数组).

 #include<iostream>
#include<iomanip>
using namespace std;
double getmedian(int *a,int *b,int n)
{
    int count=0;
    int i=0,j=0;
    double mid;
    while(count < n-1){   //循环找到合并后中间的两个中位数在两个数组中对应的下标. 

        if(a[i]<b[j]){
            i++;
            count++;
         }else{
            j++;
            count++;
         }
    }
    return (a[i]+b[i])/2.0;
}
int main(int argc,char *argv[])
{
    int a[]={1,2,3,4,5};
    int b[]={6,7,8,9,10};
    double c=getmedian(a,b,5);
    cout << "中位数是:"<<c<<endl;
    return 0;
}
分治法,时间复杂度为O(log(m+n))

假设A数组的中位数为m1,数组B的中位数为m2,例如:
a[]={1,5,6,9,10};
b[]={2,4,7,12,23};
m1=6,m2=7,由于m1

#include<iostream>
using namespace std;
int median(int *p,int n)
{
    if(n%2==0){
        return (p[n/2]+p[n/2-1])/2;   //当其元素个数为偶数时,找其下中位数和上中位数和的一半。
    }else{
        return p[n/2];
    }
}
double find_medin(int *a,int *b,int n)
{
    double m1,m2;
    if(n<=0){
        return -1;
    }
    if(n==1){
        return (a[0]+b[0])/2;   //这代表a和b数组中各有1个元素,所以,直接相加除以2;
    }
    if(n==2){
        return (max(a[0],b[0])+min(a[1],b[1]))/2;  //当a和b中各有2个元素时,找出合并后中间两个数再除于2
    }
    m1=median(a,n);   
    m2=median(b,n);
    if(m1==m2){   //相等就是中位数.
        return m1;
    }
    if(m1 < m2){
        if(n%2==0)
            return find_medin(a+n/2-1,b,n/2+1);   
        else
            return find_medin(a+n/2,b,n/2+1);
    }else{
        if(n%2==0)
            return find_medin(b+n/2-1,a,n/2+1);
        else
           return find_medin(b+n/2,a,n/2+1);
    }
}
int main(int argc,char *argv[])
{
    int a[]={1,12,10,26,38};
    int b[]={2,13,17,30,45};
    int n1=sizeof(a)/sizeof(a[0]);
    int n2=sizeof(b)/sizeof(b[0]);
    if(n1==n2){
        cout << "Medin is "<<find_medin(a,b,n1);
    }else{
        cout <<"array input errno"<<endl;
    }
   return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值