求解两个等长升序序列的中位数

原创 2016年08月30日 20:46:20

2011年计算机联考真题

题目描述:

    一个长度为L (L>=1)的升序序列S,处在第[L/2]个位置的数称为S的中位数。例如,若序列S1=(11, 13, 15, 17, 19),则S1的中位数是15,两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2= (2, 4,6,8, 20),则S1和S2的中位数是11。现在有两个等长升序序列A和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A和B的中位数。

递归解法:

基本思想:

    我们找到了A[n/2] 和 B[n/2]来比较,
    如果他们相等,那样的话,我们的搜索结束了,因为答案已经找到了A[n/2]就肯定是排序后的中位数了。
    如果我们发现B[n/2]>A[n/2],说明什么,这个数字应该在 A[n/2]->A[n]这个序列里面, 或者在 B[1]-B[n/2]这里面。
    类似的, 如果B[n/2]<A[n/2]呢?显然就是在A[0]-A[n/2]和B[n/2]-B[n]里面寻找了。
    这个递归什么时候结束呢?当然一种情况就是相等的值出现, 如果不出现等到这个n==1的时候也就结束了。

注意:

    当元素个数为奇数时舍弃中间点以前或以后部分,保留中间点
    当元素个数为偶数时:往前舍的舍掉中间点,往后舍得保留中间点,这是为了保证元素个数始终相同

代码如下:

int Find_Median( int a[], int b[], int length)
{
    if (length == 1)
        return a[0] < b[0] ? a[0] : b[0];

    int i = (length - 1)/2;
    if (a[i] == b[i])
        return a[i];
    else if(length % 2 == 0)
    {
        if (a[i]<b[i])
            // 舍掉a的中间点及以前部分,b保留中间点
            return Find_Median( &a[i+1], &b[0], length-i-1 );
        else
            //舍掉b的中间点及以前部分,a保留中间点
            return Find_Median( &a[0], &b[i+1], length-i-1 );
    }
    else
    {
        if (a[i]<b[i])
            return Find_Median( &a[i], &b[0], length-i );
        else
            return Find_Median( &a[0], &b[i], length-i );
    }
}

非递归解法

基本思想:

分别求两个序列的中位数,设为a, b,求A、B的中位数的过程如下:
     1、若a = b, 则a或b为所求,算法结束;
     2、若a < b, 则舍弃A中较小的一半,同时舍弃B中较大的一半,要求两次舍弃的长度相等;
     3、若a > b, 则舍弃A中较大的一半,同时舍弃B中较小的一半,要求两次舍弃的长度相等。
     重复步骤1 2 3,直到两个序列均只含一个元素,较小者即为所求

代码如下:

// 非递归版本
int M_Search(int A[], int B[], int n)
{
    //A、B的首位数、末位数和中位数
    int s1 = 0, d1 = n-1, s2 = 0, d2 = n-1, m1, m2;
    while(s1 != d1 || s2 != d2)
    {
        m1 = (s1 + d1)/2;
        m2 = (s2 + d2)/2;
        //满足条件 1
        if(A[m1] == B[m2])
            return A[m1];
        //满足条件 2
        if(A[m1] < B[m2])
        {
            //元素个数为奇数
            if((d1 + s1)%2 == 0)
            {
                s1 = m1;
                d2 = m2;
            }
            //元素个数为偶数
            else
            {
                s1 = m1 + 1;
                d2 = m2;
            }
        }
        //满足条件 3
        else
        {
            //奇数
            if((d2 + s2)%2 == 0)
            {
                d1 = m1;
                s2 = m2;
            }
            //偶数
            else
            {
                d1 = m1;
                s2 = m2 + 1;
            }
        }
    }

    return A[s1] < B[s2] ? A[s1] : B[s2];
}

两种算法时间复杂度均为O(logn)

5-53 两个有序序列的中位数 (25分)

5-53 两个有序序列的中位数 (25分)已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列A0,A1,⋯,AN−1A_0,A_1,⋯,A_{N−1}​​的中位数...
  • Changxing898
  • Changxing898
  • 2016年08月31日 11:55
  • 1723

求两个等长升序序列的中位数

【版权声明:转载请保留出处:blog.csdn.net/algorithm_only。邮箱:liuy0711@foxmail.com】 1.        算法要求 一个长度为L(L≥1)的升序序...
  • algorithm_only
  • algorithm_only
  • 2011年12月19日 15:47
  • 4824

减治法求解两个升序数组的中位数

#include using namespace std; int SearchMid(int a[],int b[],int n){ int s1=0,e1=n-1,s2=0,e2=n-1; ...
  • BeyondLCG
  • BeyondLCG
  • 2017年03月30日 18:22
  • 566

浙江大学PAT上机题解析之2-13. 两个有序序列的中位数

已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列A0, A1…AN-1的中位数指A(N-1)/2的值,即第[(N+1)/2]个数(A0为第1个数)。 输入格式说明...
  • chenglechao
  • chenglechao
  • 2013年09月01日 01:59
  • 3063

PAT 两个有序序列的中位数

PAT 两个有序序列的中位数
  • zhuyu__com
  • zhuyu__com
  • 2016年03月24日 21:19
  • 2688

pat 两个有序序列的中位数

代码:#include #include #include using namespace std; int a[1000000]; int main() { int n; whi...
  • xky1306102chenhong
  • xky1306102chenhong
  • 2015年08月19日 22:17
  • 483

减治算法之寻找两个递增序列的中位数

一、问题描述 寻找两个递增序列的中位数。 本算法中只能解决两个序列长度规模相等的问题,若两个序列长度规模不相等,则可以先做合并后再寻找中位数。 二、问题分析 分别计算序列A,B的中位数a,b 比较...
  • tterminator
  • tterminator
  • 2016年03月24日 10:26
  • 1597

2-13. 两个有序序列的中位数(25)

2-13. 两个有序序列的中位数(25) 时间限制 120 ms 内存限制 32000 kB 代码长度限制 8000 B ...
  • u011415955
  • u011415955
  • 2014年07月19日 22:58
  • 670

寻找两个不等长数组的中位数 Median of Two Sorted Arrays

题目源自于Leetcode。经典好题。 题目: 给出两个有序数组,长度不一定相同,一个是m一个是n,要求给出他们合并在一起之后的数组的中位数。 要求时间复杂度为O(log(m+n)),所以不可以合并数...
  • luckyjoy521
  • luckyjoy521
  • 2013年11月10日 14:42
  • 3274

两个有序序列的中位数

5-7 两个有序序列的中位数 (25分)已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列A0,A1,⋯,AN−1A_0, A_1, \cdots, A_{N-1...
  • yyxiangyu
  • yyxiangyu
  • 2017年02月22日 21:23
  • 281
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:求解两个等长升序序列的中位数
举报原因:
原因补充:

(最多只允许输入30个字)