已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列A0,A1,⋯,A*N−1的中位数指*A(N−1)/2的值,即第⌊(N+1)/2⌋个数(A0为第1个数)。
输入格式:
输入分三行。第一行给出序列的公共长度N(0<N≤100000),随后每行输入一个序列的信息,即N个非降序排列的整数。数字用空格间隔。
输出格式:
在一行中输出两个输入序列的并集序列的中位数。
输入样例1:
输出样例1:
输入样例2:
| 12
 3
 
 | 6-100 -10 1 1 1 1
 -50 0 2 3 4 5
 
 | 
输出样例2:
思路
最直接的方法就是将给定的2*n个数存入数组中,对数组排序,排序复杂度为O(nlogn)
但是这样就没有利用题目所说的两个给定数组均有序的特点
我们可以将两个有序数组合并成一个仍然有序数组,然后取中间的值即可,合并两有序数组方法为:
- 不断取出两数组中较小的数存入新数组,直到两数组为空(具体看代码)
这样时间复杂度可以是O(n),相当于遍历一遍两个数组
知识点:两有序数组的合并
代码
如下为合并方法,时间复杂度O(n)
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 
 | #include <iostream>#include <vector>
 
 using namespace std;
 
 int main() {
 int n;
 cin >> n;
 vector<int> ve1, ve2;
 for(int i = 1; i <= n; i++) {
 int id;
 cin >> id;
 ve1.push_back(id);
 }
 for(int i = 1; i <= n; i++) {
 int id;
 cin >> id;
 ve2.push_back(id);
 }
 int a = 0, b = 0;
 vector<int> ret;
 while(a < n && b < n) {
 
 if(ve1[a] < ve2[b]) {
 ret.push_back(ve1[a]);
 a++;
 } else {
 ret.push_back(ve2[b]);
 b++;
 }
 }
 while(a < n) {
 ret.push_back(ve1[a]);
 a++;
 }
 while(b < n) {
 ret.push_back(ve2[b]);
 b++;
 }
 cout << ret[(ret.size() - 1) / 2] << endl;
 return 0;
 }
 
 | 
如下为排序方法,时间复杂度O(nlogn),也可通过,不会超时
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 
 | #include <iostream>#include <algorithm>
 #include <vector>
 
 using namespace std;
 
 int main() {
 int n;
 cin >> n;
 vector<int> ve;
 for(int i = 1; i <= n; i++) {
 int id;
 cin >> id;
 ve.push_back(id);
 }
 for(int i = 1; i <= n; i++) {
 int id;
 cin >> id;
 ve.push_back(id);
 }
 sort(ve.begin(), ve.end());
 cout << ve[(2 * n - 1) / 2] << endl;
 return 0;
 }
 
 |