赞
踩
一个长度为 L ( L ≥ 1 ) 的升序序列 S,处在第 [L / 2] 个位置的数称为 S 的中位数。
例如,若序列 S1 = (11, 13, 15, 17, 19),则 S1 的中位数是 15 。
两个序列的中位数 是含它们所有元素的升序序列的中位数。例如,若 S2 = (2, 4, 6, 8, 20),则 S1 和 S2 的中位数是 11 。
给出两个有序序列 A 和 B,它们的长度相等。
设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列 A 和 B 的中位数。
输入描述
第一行是 L,表示两个有序序列 A 和 B 的长度。1 < L ≤ 1000000
第二行是序列 A,空格分隔的 L 个整数。
第三行是序列 B,空格分隔的 L 个整数。
输出描述
一个整数,A 和 B 的中位数。
用例输入 1
5
11 13 15 17 19
2 4 6 8 20
用例输出 1
11
思路1
一开始想将两组序列的数据都存储在一个容量为2*n的数组内,直接使用 sort 函数排序后输出中位数,无法AC !!!
#include<bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; cin>>n; int a[n*2+10]; for(int i = 0;i<2*n;i++) cin>>a[i]; sort(a,a+2*n); for(int i = 0 ; i<2*n;i++) cout<<a[i]<<" "; cout<<a[n -1]<<endl; return 0; }
思路2
根据中位数的定义,将问题转化为求两个有序序列中第 k 小的数,其中 k = (L+1)/2。可以使用二分查找的思想解决。
AC代码
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; cin >> n; int a[n], b[n]; for (int i = 0; i < n; i++) cin >> a[i]; for (int i = 0; i < n; i++) cin >> b[i]; int i = 0,j =0, k = 0, mid = n - 1; while (i < n && j < n && k <= mid) { if (a[i] < b[j]) { if (k == mid) cout << a[i] << endl; i++; } else { if (k == mid) cout << b[j] << endl; j++; } k++; } while (i < n && k <= mid) { if (k == mid) cout << a[i] << endl; i++,k++; } while (j < n && k <= mid) { if (k == mid) cout << b[j] << endl; j++,k++; } return 0; }
算法思路
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。