内存超限(最后一个测试点过不去???内存这么小的吗)
#include<bits/stdc++.h>
using namespace std;
int a[1000010];
int b[1000010];
int c[1000010];
void merge(int a[],int b[],int c[],int m,int n)
{
int i=0,j=0,index=0;
while(i<m&&j<n)
{
if(a[i]<=b[j])
{
c[index++]=a[i++];
}
else
{
c[index++]=b[j++];
}
}
while(i<m)
c[index++]=a[i++];
while(j<n)
c[index++]=b[j++];
// return index;
}
int main()
{
int m,n;
scanf("%d",&m);
for(int i=0;i<m;i++)
{
scanf("%d",&a[i]);
}
sort(a,a+m);
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&b[i]);
}
sort(b,b+n);
merge(a,b,c,m,n);
printf("%d\n",c[(m+n-1)/2]);
return 0;
}
看了大神的博客
然后知道了
归并排序超内存了
大神用了队列的方法
维护两个队列,比较对头大小,循环出列
第一个队列存好后
把第二个队列边读
边和第一个队列比较,选择出队
这样就不用一次存完第二个队列
解决超内存的问题
第一、二个序列分别有n、m个元素
所以需要从队头剔除(n+m-1)/2个元素
最后答案就是两个队头的最小值
而最终答案在第一第二个队列中的情况要分开处理
若答案在第二个队列中
在输入数据时就可以提前得出答案并退出
若答案在第一个队列中,要二次出队才能找到答案
注意点:
在所有元素入队列完毕后,把INT_MAX入队列
一是这样队列永不为空,方便处理
二是,题目中的long int因为内存限制的原因,并不会为最终答案,只是干扰数据
所以每次遇到这样的干扰数据把他设为INT_MAX即可
#include<bits/stdc++.h>
using namespace std;
int main()
{
queue<int>a,b;
long long tnum;
int n,m,num,cnt=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%lld",&tnum);
num=min((long long)INT_MAX,tnum);
a.push(num);
}
a.push(INT_MAX);
scanf("%d",&m);
for(int i=0;i<m;i++)
{
scanf("%lld",&tnum);
num=min((long long)INT_MAX,tnum);
b.push(num);
if(cnt==(n+m-1)/2)
{
printf("%d",min(a.front(),b.front()));
return 0;
}
if(a.front()<b.front())
{
a.pop();
}
else
b.pop();
cnt++;
}
b.push(INT_MAX);
for(;cnt<(n+m-1)/2;cnt++)
{
if(a.front()<b.front())
a.pop();
else
b.pop();
}
printf("%d",min(a.front(),b.front()));
return 0;
}
再次感叹下
这个大大为啥这么强
但是有一个不理解的点
为什么第一个队列要分出来才能输出
【懂了!!!】
就是如果第一个队列的长度大于第二个
那其实还没有到中位数就直接循环结束了
所以还应有下一个循环进行遍历
双针法:(第二个数组边读边读入)
#include <cstdio>
#include <cstdlib>
const int INF = 0x7fffffff;
int main() {
int l1, l2, i, j, count = 0;
int *a1, a2;
scanf("%d", &l1);
a1 = (int *)malloc((l1 + 1) * sizeof(int));
for (i = 0; i < l1; i++)
scanf("%d", a1 + i);
*(a1 + l1) = INF;
scanf("%d", &l2);
//a2 = (int *)malloc((l2 + 1) * sizeof(int));
//for (i = 0; i < l2; i++)
// scanf("%d", a2 + i);
//*(a2 + l2) = INF;
int mid = (l1 + l2 - 1) / 2; // l1 = mediapos
i = j = 0;
scanf("%d", &a2);
while (count < mid)
{
if (*(a1 + i) < a2) i++;
else {
j++;
if (j < l2)
{
scanf("%d", &a2);
}
else if (j == l2)
a2 = INF;
else
break;
}
count++;
}
printf("%d\n", *(a1 + i) < a2 ? *(a1 + i) : a2);
return 0;
}