zoukankan      html  css  js  c++  java
  • 两个等长升序序列找中位数

    题目

       一个长度为 L 的升序序列 S,处在第个位置的数称为 S 的中位数。例如,若序列 ,则  的中位数是 15,两个序列的中位数是含他们所有元素的升序序列的中位数。例如,若 ,则  和  的中位数是 11。现在有两个等长升序序列 A 和 B,试设计一个算法,找出两个序列 A 和 B 的中位数。

    分析

    暴力

      把 A 和 B 混合到一起再找中位数。实现方法简单且不为本篇文章讨论重点,不再详细叙述。

    减治

      将升序序列左右两边同时减去相等个数的数字,中位数不变。

      令两个升序序列 A , B 的中位数为 a , b,求解过程如下:

        ① 若 a = b,则 a 或 b 即为所求中位数。

        ② 若 a < b,则舍弃序列 A 中较小的一半,同时舍弃序列 B 中较大的一半,要求两次舍弃的长度相等。

        ③ 若 a > b,则舍弃序列 A 中较大的一半,同时舍弃序列 B 中较小的一半,要求两次舍弃的长度相等。

      在保留的两个升序序列中,重复过程 ① ,② ,③,直到两个序列中均只含一个元素时为止,较小者即为所求的中位数。 

    ① a = b

      a = b时,容易得到两个序列在数轴上的大小关系,虽然左右两边并没有绝对大小关系,但是中位数的选取只跟中间位置有关,所以并不影响。

    ② a != b

      a != b时,以 a < b 为例。

      对于奇数个数序列:

        因为中位数只与升序序列的位置有关,通过左图中的有/无绝对大小关系可得 蓝1,蓝2,绿4,绿5 代表的四个数绝对不可能在中间位置(5),所以把他们删去,即中位数的大小范围为 [a , b] 。

      对于偶数个数序列:

        还是那句话因为中位数只与升序序列的位置有关,通过右图中的有/无绝对大小关系可得 蓝1,蓝2,绿3,绿4 代表的四个数绝对不可能在中间位置(4),所以把他们删去,即中位数的大小范围为 ( a , b ]。

     

    实现

    int M_Search(int A[], int B[], int n) 
    {
        int s1=0,d1=n-1,m1,s2=0,d2=n-2,m2;//A,B序列的首位数、中位数、末位数
        while (s1 != d1 || s2 != d2) 
        {
            m1=(s1+d1)/2;
            m2=(s2+d2)/2;
            if (A[m1]==B[m2])             //当两个中位数相等,即为所求中位数
                return A[m1];
            else if (A[m1]<B[m2]) 
            {
                if((s1+d1)%2==0)          //当元素个数为奇数
                { 
                    s1=m1;                //舍弃A中间点以前的部分且保留中间点
                    d2=m2;                //舍弃B中间点以后的部分且保留中间点
                }
                else                      //当元素个数为偶数
                {                      
                    s1=m1+1;              //舍弃A中间点及中间点以前的部分
                    d2=m2;                //舍弃B中间点以后的部分且保留中间点
                }
                
            }
            else                          //同理
            {
                if ((s2+d2)%2==0) 
                {
                    d1=m1;
                    s2=m2;
                }
                else 
                {
                    d1=m1;
                    s2=m2+1;
                }
            }
    
        }
        return A[s1]<B[s2]?A[s1]:B[s2];
    }
  • 相关阅读:
    Photon Server 实现注册与登录(五) --- 服务端、客户端完整代码
    机器学习小白笔记系列——支持向量机
    机器学习小白笔记系列——条件随机场
    机器学习小白笔记系列——EM算法
    机器学习小白笔记系列——线性回归
    多元统计分析学习笔记——概论及数据描述知识点回顾
    ORACLE的SPFILE与PFILE
    简单的点餐系统
    Linux系统中CTG的安装,应用程序开发以及调试
    Netstat命令
  • 原文地址:https://www.cnblogs.com/VividBinGo/p/13100510.html
Copyright © 2011-2022 走看看