【题目来源】
https://www.acwing.com/problem/content/description/3822/
【问题描述】
一个长度为 L(L≥1)的升序序列 S,处在第 ⌈L/2⌉ 个位置的数称为 S 的中位数。
两个序列的中位数是含它们所有元素的升序序列的中位数。
例如,若序列 S1=(11,13,15,17,19),S2=(2,4,6,8,20),则 S1 和 S2 的中位数是 11。
现在有两个等长升序序列 A 和 B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列 A 和 B 的中位数。
【数据范围】
两个序列的长度均不超过 10^5。
序列中的元素取值范围 [−10^9,10^9]。
【算法分析】
分别求出序列A和B的中位数,记为a和b,有下列三种情况:
(1) 若a=b,则a或b即为两个序列的中位数,算法结束。
(2) 若a<b,则中位数只能出现在a和b之间,则舍弃序列A中较小的一半,同时舍弃序列B中较大的一半,并且要求舍弃的长度相等。
(3) 若a>b,则中位数只能出现在b和a之间,则舍弃序列A中较大的一半,同时舍弃序列B中较小的一半,并且要求舍弃的长度相等。
重复上述过程,直至两个序列都只有一个元素,则较小者为所求。
【算法代码一】
#include <iostream>
using namespace std;
int findMed(int* a,int* b,int n) {
int alow,ahigh,blow,bhigh,amid,bmid;
alow=blow=0;
ahigh=bhigh=n-1;
while(alow!=ahigh || blow!=bhigh) {
amid=(alow+ahigh)/2;
bmid=(blow+bhigh)/2;
if(a[amid]==b[bmid]) return a[amid];
else if(a[amid]<b[bmid]) {
if((alow+ahigh)%2==0) {
alow=amid;
bhigh=bmid;
} else {
alow=amid+1;
bhigh=bmid;
}
} else {
if((blow+bhigh)%2==0) {
blow=bmid;
ahigh=amid;
} else {
blow=bmid+1;
ahigh=amid;
}
}
}
return a[alow]<b[blow]?a[alow]:b[blow];
}
int main(){
int* a;
int* b;
int mid;
int n;
cin>>n;
a=new int[n];
b=new int[n];
for(int i=0;i<n;i++) cin>>a[i];
for(int i=0;i<n;i++) cin>>b[i];
cout<<findMed(a,b,n)<<endl;
return 0;
}
/*
in1:
5
11 13 15 17 19
2 4 6 8 20
out1:
11
int2:
5
3 5 10 11 13
15 16 17 19 20
out2:
13
*/
【算法代码二】
#include<bits/stdc++.h>
using namespace std;
int findMed(vector<int>& a,vector<int>& b) {
vector<int> t;
int le=0, ri=0;
int n=a.size(), m=b.size();
while(le<n && ri<m) {
if(a[le]<=b[ri]) t.push_back(a[le++]);
else t.push_back(b[ri++]);
}
while(le<n) t.push_back(a[le++]);
while(ri<m) t.push_back(b[ri++]);
le=0, ri=n+m-1;
return t[(n+m)/2-1];
}
int main() {
vector<int> a,b;
int x;
int n;
cin>>n;
for(int i=0; i<n; i++) {
cin>>x;
a.push_back(x);
};
for(int i=0; i<n; i++) {
cin>>x;
b.push_back(x);
};
cout<<findMed(a,b)<<endl;
return 0;
}
/*
in1:
5
11 13 15 17 19
2 4 6 8 20
out1:
11
int2:
5
3 5 10 11 13
15 16 17 19 20
out2:
13
*/
【参考文献】
https://www.acwing.com/solution/content/59699/
https://www.freesion.com/article/65131042399/
https://blog.csdn.net/ldanduo/article/details/8147113
https://www.cnblogs.com/VividBinGo/p/13100510.html