算法第二章上机实践报告

题目:   7-3 两个有序序列的中位数 (20 分)  

已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列A​0​​,A​1​​,⋯,A​N−1​​的中位数指A​(N−1)/2​​的值,即第⌊(N+1)/2⌋个数(A​0​​为第1个数)。

输入格式:

输入分三行。第一行给出序列的公共长度N(0<N≤100000),随后每行输入一个序列的信息,即N个非降序排列的整数。数字用空格间隔。

输出格式:

在一行中输出两个输入序列的并集序列的中位数。

输入样例1:

5
1 3 5 7 9
2 3 4 5 6

输出样例1:

4

输入样例2:

6
-100 -10 1 1 1 1
-50 0 2 3 4 5

输出样例2:

1



题目大意:求两个组数的中位数,并要求时间复杂度为O(logN)

解题思路二分+递归
既然时间复杂度是O(logN),那么一看就知道用二分法,在两组数a,b中各取中位数ma,mb,比较大小。
数组长度为n —>
中位数为第n个 —>数组必有n-1个数比中位数小
若a[ma]==b[mb] —> 第n个数和第n+1个数都是a[ma] —> 中位数为a[ma]
若a[ma]<b[mb] —> 中位数在a[ma]的右边,b[mb]的左边(一定要有n-1个数比中位数小)
若a[ma]>b[mb] —> 中位数在a[ma]的左边,b[mb]的右边(同上)
最后剩余的判断范围的奇偶会影响下一次递归的参数,需判断


AC代码:
算法第二章上机实践报告
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n;
 4 const int maxn=1e5+5;
 5 int a[maxn],b[maxn];
 6 int binary(int la,int ra,int lb,int rb){
 7     if(la>=ra||lb>=rb) return a[la]>b[lb]?b[lb]:a[la];
 8     int ma=(la+ra)>>1,mb=(lb+rb)>>1;
 9     if(a[ma]==b[mb]) return a[ma];
10     else if(a[ma]<b[mb]){
11         if((ra-la+1)&1) return binary(ma,ra,lb,mb);
12         else return binary(ma+1,ra,lb,mb);
13     }else{
14         if((rb-lb+1)&1) return binary(la,ma,mb,rb);
15         else return binary(la,ma,mb+1,rb);
16     }
17 }
18 int main(){
19     cin>>n;
20     for(int i=0;i<n;i++) cin>>a[i];
21     for(int i=0;i<n;i++) cin>>b[i];
22     cout<<binary(0,n-1,0,n-1)<<'\n';
23     return 0;
24 } 
View Code

 

复杂度分析:空间复杂度没什么好说的就两个长度为n的数组,且n最大值为1e5。

                                时间复杂度则因为采取了二分法所以为O(logN)


心得体会:加强了对二分法的灵活运用,更加熟练掌握二分法。
上一篇:移动端 meta


下一篇:P1351 联合权值