持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第31天,点击查看活动详情
题目描述:
已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列A0,A1,⋯,AN−1的中位数指A(N−1)/2的值,即第⌊(N+1)/2⌋个数(A0为第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
代码长度限制 16 KB
时间限制 400 ms
内存限制 64 MB
PS: 这里讲两种方法:
- 1.使用list头文件
- 2.使用set头文件
list思路:
思路分析:
1.创建两个list用来存储两行的数据
2.创建两个list的迭代器用来标记两个list的头部
3.迭代,比较(注意:只需要比较前n个,因为是中位数)
4.输出
list思路代码:
#include<iostream>
#include<list>
using namespace std;
int main()
{
//创建两个list
list<int>a, b;
int n, x;
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);
}
int temp;
list<int>::iterator p = a.begin();
list<int>::iterator q = b.begin();
for (int cnt = 0; cnt < n; cnt++) {
if (*p > *q) {
temp = *q;
q++;
}
else {
temp = *p;
p++;
}
}
cout << temp;
}
提交结果:
结果分析:
耗时:71ms
内存:6728KB
set思路:
思路分析:
1.由于set具有自动排序的功能,但注意到有重复数字,所以只需要创建一个multiset,让2*n个数字一同放入multiset中
2.迭代multiset,找到中位数
set思路代码:
#include<iostream>
#include<set>
using namespace std;
int main()
{
int n, x;
cin >> n;
multiset<int>s;
for (int i = 0; i < 2 * n; i++) {
cin >> x;
s.insert(x);
}
multiset<int>::iterator it = s.begin();
for (int i = 0; i < n - 1; i++) {
it++;
}
cout << *it;
}
提交结果:
结果分析:
耗时:103ms
内存:9808KB
两种思路比较:
毫无疑问,list在这里更胜一筹,因为这两个list是基本有序的,所以用list只需要迭代n个就可以找到中位数
反观set由于两个加在一起需要排序,浪费了很多时间,效率不高 PS: 这边建议使用list思路代码~