求解两个等长升序序列的中位数
来源:互联网 发布:手机测试分贝软件 编辑:程序博客网 时间:2024/05/17 02:31
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)
0 0
- 求解两个等长升序序列的中位数
- 求两个等长升序序列的中位数
- 求两个等长升序序列的中位数
- 求两个等长升序序列的中位数 .
- 求两个等长升序序列的中位数
- 求两个等长有序序列的中位数
- 求两个升序序列的中位数
- 求两个已排序(升序)等长的整数数组所有元素的中位数
- 两个升序数组的中位数
- 求两个等长升序序列中每个序列取一个元素求和的第K小元素
- 求两个等长有序数组的中位数
- 求两个等长有序数组的中位数
- 算法 -- 求两个等长数组的中位数
- 关于在一个序列中寻找中位数和第K大的数(在两个等长有序数组中寻找中位数)
- 两个等长有序数组求中位数
- 减治法-两个序列的中位数
- 两个有序序列的中位数
- 两个有序序列的中位数
- 12期 9月期刊自荐
- Multiple Contexts have a path of "/***"
- 文件IO操作的意义
- Java的类名与文件名必须一致
- Python中的sorted以及operator.itemgetter的用法
- 求解两个等长升序序列的中位数
- APPScan配置URL连接后无法正常访问地址原因
- linux find命令
- codeforces#369Div2(711B)Chris and Magic Square
- Intent的基本用法以及Activity的生命周期和启动模式
- Windows下 免安装版MySQL配置
- unity插件使用--Unitybmob插件使用记录
- 数据库事务隔离级别
- 本博客搬迁