PAT-ADVANCED1029——Median

我的PAT-ADVANCED代码仓:https://github.com/617076674/PAT-ADVANCED

原题链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805466364755968

题目描述:

题目翻译:

1029 中位数

给定N个整数的递增序列S,中位数是中间位置的数字。 例如,S1 = {11,12,13,14}的中位数为12,S2 = {9,10,15,16,17}的中位数为15。两个序列的中位数定义为非递减序列的中值,包含两个序列的所有元素。 例如,S1和S2的中位数是13。

给定两个递增的整数序列,你需要找到它们的中位数。

输入格式:

每个输入文件包含一个测试用例。每个测试用例占两行,每行给出了序列的信息。对每个序列,其第一个正整数N(<= 2 * 10 ^ 5),代表序列的大小。接下来的N个整数由一个空格分隔。题目保证所有的整数都在long int类型范围内。

输出格式:

对每个测试用例,你需要输出两个给定序列的中位数。

输入样例:

4 11 12 13 14
5 9 10 15 16 17

输出样例:

13

知识点:双指针

思路:双指针遍历两个序列即可

本题只需双指针遍历两个序列即可。但是如果用数组或是vector来存储两个序列,测试点8会内存超限。因此我们使用队列来存储两个序列。

在读入第二个序列的同时,和第一个序列开始进行比较,每读入一个新值,队列1或队列2就会有一个值出队列。一旦出队列的元素达到了中位数的索引值(N1 + N2 - 1) / 2,就找到了该中位数,直接return。

需要注意的是,读取完第二个序列后我们未必已经找到了中位数。如果还没有找到中位数,需要继续对两队列进行出队操作寻找中位数。

一个小技巧是,读取完每个序列之后为该序列入队一个INF数据,INF = 0x7fffffff,为long int型的最大值,这样可以避免对某个队列为空的情况进行讨论

C++代码:

#include<iostream>
#include<vector>
#include<queue>

using namespace std;

int INF = 0x7fffffff;

int main() {
	int N1, N2;
	scanf("%d", &N1);
	queue<int> nums1, nums2;
	int num;
	for(int i = 0; i < N1; i++) {
		scanf("%d", &num);
		nums1.push(num);
	}
	nums1.push(INF);
	scanf("%d", &N2);
	int count = 0;
	for(int i = 0; i < N2; i++) {
		scanf("%d", &num);
		nums2.push(num);
		if(count == (N1 + N2 - 1) / 2){
			printf("%d\n", min(nums1.front(), nums2.front()));
			return 0;
		}
		if(nums1.front() <= nums2.front()){
			nums1.pop();
		}else{
			nums2.pop();
		}
		count++;
	}
	nums2.push(INF);
    for(; count < (N1 + N2 - 1) / 2; count++) {
        if(nums1.front() < nums2.front())    
            nums1.pop();
        else                         
            nums2.pop();
    }
    printf("%d", min(nums1.front(), nums2.front()));
	return 0;
}

C++解题报告:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值