7-3 两个有序序列的中位数 (20分) log n的解法


//查找两个等长有序系列的中位数 时间复杂度为logn

/* 解题思路
中位数满足大于且仅大于n-1个元素,小于且仅小于n个元素
a_mid = (a_left + a_right) / 2
b_mid = (b_left + b_right) / 2
当a[a_mid]=b[b_mid]时,中位数为a[a_mid]
当a[mid]<b[mid]时:
若n为奇数,中位数存在范围为a[a_mid...a_right], b[b_left...b_mid]
若n为偶数,中位数存在范围为a[a_mid+1...a_right], b[b_left...b_mid]
当a[mid]>b[mid]时:
若n为奇数,中位数存在范围为a[a_left...a_mid], b[b_mid...b_right]
若n为偶数,中位数存在范围为a[a_left...a_mid], b[b_mid+1...b_right]
当问题规模为1时,只有两个数字,直接输出较小的值
*/


#include <iostream>
using namespace std;
int BinarySearch(int *a,int left1,int right1,int left2,int right2){

if(left1==right1){                                          //如果查找数组包含两个数字,则直接找出中位数
return a[left1] < a[left2] ? a[left1] : a[left2];
}

int mid1 = (left1+right1)/2;
int mid2 = (left2+right2)/2;
if(a[mid1]==a[mid2]) {                               //如果两个中位数相等,则找到退出
return a[mid1];
}
else if(a[mid1]<a[mid2]){                         //第1个数组查找范围为右半部分,第2个数组查找范围为左半部分
if ((right1 - left1 + 1) % 2 == 0) mid1 += 1;                       //如果n为偶数,右半部分的开始位置为中位数位置加1
left1 = mid1;
right2 = mid2;

}
else if(a[mid1]>a[mid2]){                         //第1个数组查找范围为左半部分,第2个数组查找范围为右半部分
if ((right2 - left2 + 1) % 2 == 0) mid2 += 1;                      //如果n为偶数,右半部分的开始位置中位数位置加1
left2 = mid2;
right1 = mid1;
}
BinarySearch(a,left1,right1,left2,right2);
}

int main (){
int n;
cin>>n;
int a[2*n];
for(int i=0;i<2*n;i++){
cin>>a[i];
}
cout<<BinarySearch(a,0,n-1,n,2*n-1)<<endl;
}

posted @ 2020-10-10 10:20  吹梦西洲  阅读(323)  评论(0编辑  收藏  举报