两个序列的中位数问题

题目

一个长度为 L ( L 1 ) L(L\ge1) 的升序序列S,处在第[L/2]个位置的数称为S的中位数。例如,若序列 S 1 = ( 11 , 13 , 15 , 17 , 19 ) S_1=(11,13,15,17,19) ,则S_1的中位数是15,两个序列的中位数是含他们所有元素的升序序列的中位数,例如,若 S 2 = ( 2 , 4 , 6 , 8 , 20 ) S_2=(2,4,6,8,20) ,则 S 1 S_1 S 2 S_2 的中位数是11,现在需要找出序列 A A B B 的中位数。

思路:

分别求两个升序序列 A B A、B 的中位数,设为 a a b b ,求序列 A B A、B 的中位数过程如下:

  1. a = b a=b ,则 a a b b 即为所求中位数,算法结束,
  2. a < b a<b ,则舍弃序列 A A 中较小的一半,同时舍弃序列 B B 中较大的一半,要求两次舍弃的长度相等,
  3. a > b a>b ,则舍弃序列 A A 中较大的一半,同时舍弃序列 B B 中较小的一半,要求两次舍弃的长度相等,
    在保留的两个升序序列中,重复过程 1 2 3 1、2、3 ,直到两个序列中均只含一个元素为止,较小者即为所求的中位数。
思路依据:
  1. a + b a+b 的情形,若将 B B 合并到 A A 中,则 b b 的前半部分放到 A A 的前半部分, b b 的后半部分放到 A A 的后半部分,所以中位数不改变,
  2. a < b a<b 的情形,若将 B B 合并到 A A 中,则至少 b b 及前半部分放到 A A 的前半部分,此时最好的情况 b b 就是中位数,那么 b b 的前半部分就不可能包含中位数,显然 a a 的后半部分也不可能包含中位数,所以在两边同时删去一半,对最终结果没有影响。
  3. a > b a>b 的情形同 2 2 一样。
代码实现:
#include<iostream>
#include<stdio.h>
using namespace std;

int M_search(int A[], int B[], int n){
    int s1=0, d1=n-1, m1;
    int s2=0, d2=n-1, m2;
    while(s1 != d1 || s2 != d2){
        m1 = (s1+d1)/2;
        m2 = (s2+d2)/2;
        if(A[m1] == B[m2])
            return A[m1];
        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){
                s2=m2;
                d1=m1;
            }
            else{
                s2=m2+1;
                d1=m1;
            }
        }
    }
    return A[s1] < B[s2] ? A[s1]:B[s2];
}

int main(){
   int A[5] = {11, 13, 15, 17, 19};
   int B[5] = {2, 4, 6, 8, 20};
   printf("%d\n", M_search(A, B, 5));
}

分析:
  1. 时间复杂度为 O ( log 2 n ) O(\log_2n) ,空间复杂度为 O ( 1 ) O(1)
  2. 当然本题可以采用先合并 A A B B ,在求中位数的办法,但是复杂度为 O ( n ) O(n) ,不是最优算法。
发布了37 篇原创文章 · 获赞 30 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_40941722/article/details/93875774