1029 Median (25 分)(two pointer)

1029 Median (25 分)(two pointer)

Given an increasing sequence S of N integers, the median is the number at the middle position. For example, the median of S1 = { 11, 12, 13, 14 } is 12, and the median of S2 = { 9, 10, 15, 16, 17 } is 15. The median of two sequences is defined to be the median of the nondecreasing sequence which contains all the elements of both sequences. For example, the median of S1 and S2 is 13.

Given two increasing sequences of integers, you are asked to find their median.

Input Specification:

Each input file contains one test case. Each case occupies 2 lines, each gives the information of a sequence. For each sequence, the first positive integer N (≤2×10​5​​ ) is the size of that sequence. Then N integers follow, separated by a space. It is guaranteed that all the integers are in the range of long int.

Output Specification:

For each test case you should output the median of the two given sequences in a line.

Sample Input:
4 11 12 13 14
5 9 10 15 16 17
Sample Output:
13
题目大意

定义两组序列中位数为合并两组序列后非递减序列的中位数,先给定两组序列,求他们合并序列的中位数。

分析

个人思路:
本题提交时使用set发现测试点5-8(从0开始)内存超限,然后改用vector均出现运行超时和内存超限,具体的思路时,最坏的情况下存放两组2*105个4字节的整型数消耗内存为1.52588MB(超过程序要求的运行内存),因此考虑智能存放部分元素(i.e.,存放一半元素占用0.75MB不会内存超限),更进一步,存放在数组(或集合)中的数量设定为总数的一半,即(m+n)/2,若使用vector存放数,则在尾部追加数的时候会进行排序,若使用set,因为set是有序的,此步可省。当容器的容量达到(m+n)/2时,则需要删除或者覆盖尾部元素。最后取尾部元素即为中位数。思路没问题,但是内存超限或者运行超时,内存超限我猜测是因为set或者vector占用的内存除了存放数据外还要维护因创建STL消耗的内存,这个容量非常大,并且通过查阅可知,STL系列容器比较消耗内存,在对内存要求比较苛刻的环境下慎用,尽力使用基本元素的数组存储。

正确思路::
本题参考博客1写出源码。思路是:本题考查 two pointer知识,先开一个200010的数组,将第一个序列存放其中,并将数组的a[n+1]设为0x7fffffff正兴最大数(用于终止while循环),在输入第二个序列时,看是否大于数组的前几个数,若在输入完第二组序列时仍未找到中位数,则说明第二个序列数普遍偏小并且序列的个数小,可以推断中位数在第一个序列中,接下来只需在第一个序列中找中位数即可。本算法的本质是遍历序列过程中找出前(m+n)/2个数,若全部找出则找出的时访问的那个数或者他前面的一个数即为整个序列的中位数,two pointer分别是midpos和i。

注:关于two pointer参考博客总结2.

#include <iostream>
using namespace std;
int a[200010];
int main() {
    int n,n1,j=1,i,count=0,k,temp;
    scanf("%d",&n);
    a[n+1]=0x7fffffff;
    for(k=1; k<=n; k++) cin>>a[k];
    cin>>n1;
    int midpos=(n1+n+1)/2;
    for(i=1; i<=n1; i++) {
        scanf("%d",&temp);
        while(a[j]<temp) {
            count++;
            if(count==midpos) {
                cout<<a[j];
            }
            j++;
        }
        count++;
        if(count==midpos) {
            cout<<temp;
        }
    }
    while(j<=n) {
        count++;
        if(count==midpos) {
            cout<<a[j];
        }
        j++;
    }
    return 0;
}

  1. https://www.liuchuo.net/archives/2248 ↩︎

  2. https://www.liuchuo.net/archives/2248 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值