The Median
题目描述
给出一个长度为 N N N的非负整数序列 A i A_i Ai,对于所有 1 ≤ k ≤ ( N + 1 ) / 2 1 ≤ k ≤ (N + 1) / 2 1≤k≤(N+1)/2,输出 A 1 , A 1 ∼ A 3 , … , A 1 ∼ A 2 k − 1 A_1, A_1 \sim A_3, …,A_1 \sim A_{2k - 1} A1,A1∼A3,…,A1∼A2k−1的中位数。即前 1 , 3 , 5 , … 1,3,5,… 1,3,5,…个数的中位数。
输入格式
第 1 1 1行为一个正整数 N N N,表示了序列长度。
第 2 2 2行包含 N N N个非负整数 A i ( A i ≤ 1 0 9 ) A_i (A_i ≤ 10^9) Ai(Ai≤109)。
输出格式
共 ( N + 1 ) / 2 (N + 1) / 2 (N+1)/2行,第 i i i行为 A 1 , A 3 , … , A 2 k − 1 A_1, A_3, …, A_{2k - 1} A1,A3,…,A2k−1的中位数。
样例 #1
样例输入 #1
7
1 3 5 7 9 11 6
样例输出 #1
1
3
5
6
提示
对于 20 % 20\% 20%的数据, N ≤ 100 N ≤ 100 N≤100;
对于 40 % 40\% 40%的数据, N ≤ 3000 N ≤ 3000 N≤3000;
对于 100 % 100\% 100%的数据, N ≤ 100000 N ≤ 100000 N≤100000。
题意:
给出一个长度为 N N N的非负整数序列 A i A_i Ai,输出前 1 , 3 , 5 , … 1,3,5,… 1,3,5,…个数的中位数。
思路:
结合 黑匣子 的思想(对顶堆做法)
对于一个 含有 n
(奇数)个元素的序列,其 中位数 显然为 第 n + 1 >> 1
大值,而 对顶堆 可用于 动态求整个序列的第 k
大值。那么做法就不难想到了。总的时间复杂度 为
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)
本题又是一道 对顶堆模板题,上代码。
代码 I:(将目标值放在大根堆堆顶)
#define _CRT_SECURE_NO_WARNINGS 1
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 10;
int a[N];
int n;
signed main()
{
int T = 1; //cin >> T;
while (T--)
{
cin >> n;
for (int i = 1; i <= n; ++i)
{
scanf("%lld", &a[i]);
}
priority_queue<int> max_heap;
priority_queue<int, vector<int>, greater<int>> min_heap;
for (int i = 1; i <= n; ++i)
{
max_heap.push(a[i]);
if (i & 1)
{
int k = i + 1 >> 1;
if (max_heap.size() > k && max_heap.size())
{
min_heap.push(max_heap.top());
max_heap.pop();
}
printf("%lld\n", max_heap.top());
if (max_heap.size() < k + 1 && min_heap.size())
{
max_heap.push(min_heap.top());
min_heap.pop();
}
}
else
{
int k = i + 2 >> 1;
if (max_heap.size() > k && max_heap.size())
{
min_heap.push(max_heap.top());
max_heap.pop();
}
}
}
}
return 0;
}
代码 II:(写法更简便,将目标值放在小根堆堆顶)
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
priority_queue<int,vector<int>,greater<int>> heap1;
priority_queue<int,vector<int>,less<int>>heap2;
int limit=(int)(n+1)/2;
int co=0;
for(int i=1;i<=n;i++)
{
heap1.push(a[i]);
while(heap1.size()>co)
{
auto t=heap1.top();
heap1.pop();
heap2.push(t);
}
if(i%2!=0)
{
cout<<heap2.top()<<endl;
heap1.push(heap2.top());
heap2.pop();
co++;
}
}
return 0;
}