问题描述:
中位数问题,长度为L的升序序列S的中位数的位置为[L/2](对下取整)
求两个等长序列A和B的联合中位数
算法描述:
二分法实现,空间复杂度O(1),时间复杂度O(log~2(n))
为了节省计算,首先比较中位数,
如果两者中位数相等,则联合中位数为AB中位数
如果A的中位数小于B的中位数,则去掉A中小的一半元素,B中大的一半元素
如果B的中位数小于A的中位数,上述方法同样适用
对剩下元素进行排序,找到中位数
简单代码
#include<iostream>
using namespace std;
//总的原则是,左边去除元素数量等于右边去除数量,中位数取小
int findMid(int A[], int B[], int L){
int s1=0,m1,e1=L-1,s2=0,m2,e2=L-1;
while(s1!=e1 || s2!=e2) {
m1 = (s1 + e1) / 2;
m2 = (s2 + e2) / 2;
//除了判断大于小于的情况,还有判断较小一方中位数奇偶的情况
//对于中位数标号为奇数的情况,需要将小的一方多排除一位
//因为取中位数采取向低位取整,奇数时左侧少去除一位
if(A[m1]==B[m2]){
return A[m1];
}
if(A[m1]<B[m2]){
if((s1+e1)%2 == 0){
s1 = m1;
e2 = m2;
}
else{
s1 = m1 + 1;
e2 = m2;
}
}
else{
if((s2+e2)%2 == 0){
s2 = m2;
e1 = m1;
}
else{
s2 = m2 + 1;
e1 = m1;
}
}
}
return A[s1]<B[s2]? A[s1]:B[s2];
}
int main(){
int S1[5]={11,13,15,17,19},S2[5]={2,4,6,8,20};
int mid;
mid = findMid(S1,S2,5);
cout << mid;
return 0;
}