1029 Median [Queue] + LeetCode 寻找两个有序数组的中位数

题目链接Median

用long int写一直爆内存,网上一查答案只会是int,心态崩了。。。

题目大意是给你两个序列,求他们合并之后的中位数。

首先,如果用数组写,内存就炸了。sort一时爽,一直sort一直爽

中位数,根据算法导论的定义,当n为奇数时,他是第(n+1)/2个顺序统计量;当n为偶数时,他是第n/2个顺序统计量。通俗来说,就是这个数前面有p个,后面有p个。那么我们只需要找到前p个数就知道中位数了。题目给了两个数列,很明显要用队列来做。

这题输入的序列已经是升序了所以可以直接用队列存(想想为什么)。先把第一列数用一个队列q1存起来,然后处理第二列q2。比较q1.top()和q2.top(),谁小就让它出队。如果已经出了(m+n-1)/2个数了,答案最终就是这两个队列中最小的top()。如果没有,剩下未空的队列继续出队得到答案。

这里有两个点需要注意一下,在处理第二个序列时,边进队列边处理可以减少内存开销。还有就是为每个队列都在最后push一个INT_MAX,这样处理起来比较方便。 

#include<bits/stdc++.h>
#define maxn 200005
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
int n,m,p,cnt,ans,x;
queue<int> q1,q2;
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&x);
        q1.push(min(x,INT_MAX));
    }
    q1.push(INT_MAX);
    scanf("%d",&m);
    cnt=0;
    for(int i=0;i<m;i++)
    {
        scanf("%d",&x);
        q2.push(min(x,INT_MAX));
        if(cnt==(n+m-1)/2)
        {
            ans=min(q1.front(),q2.front());
            printf("%d\n",ans);
            return 0;
        }
        if(q2.front()>q1.front())
            q1.pop();
        else
            q2.pop();
        cnt++;
    }
    q2.push(INT_MAX);
    for(;cnt<(n+m-1)/2;cnt++)
    {
        if(q2.front()>q1.front())
            q1.pop();
        else
            q2.pop();
    }
    ans=min(q1.front(),q2.front());
    printf("%d\n",ans);
    return 0;
}
View Code

4. 寻找两个有序数组的中位数

题目思路在上面

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        if(nums1.size()==0)//数组1有可能为空
        {
            int t=nums2.size();
            if(t%2==1)
                return nums2[t/2];
            else
                return (double)(nums2[t/2]+nums2[t/2-1])/2;
        }
        if(nums2.size()==0)//数组2有可能为空
        {
            int t=nums1.size();
            if(t%2==1)
                return nums1[t/2];
            else
                return (double)(nums1[t/2]+nums1[t/2-1])/2;
        }
        queue<int> q1,q2;
        double ans;
        int cnt=0,tmp,n=nums1.size()+nums2.size(),flag=0;
        for(int i=0;i<nums1.size();i++)//把数组放到队列中
            q1.push(nums1[i]);
        q1.push(INT_MAX);//加一个INT_MAX方便处理
        for(int i=0;i<nums2.size();i++)
            q2.push(nums2[i]);
        q2.push(INT_MAX);
        if(n%2==0)//判断数组总的个数是奇数还是偶数
            flag=1;
        n=(n-1)/2;//需要弹出的个数
        for(int i=0;i<nums2.size();i++)
        {
            if(cnt==n)//已经弹出n个
            {
                if(flag)//偶数要取两个数
                {
                    if(q1.front()>q2.front())
                    {
                        tmp=q2.front();
                        q2.pop();
                    }
                    else
                    {
                        tmp=q1.front();
                        q1.pop();
                    }
                    ans=(double)(tmp+min(q1.front(),q2.front()))/2;
                    return ans;
                }
                else
                    return min(q1.front(),q2.front());
            }
            if(q2.front()>q1.front())
                q1.pop();
            else
                q2.pop();
            cnt++;
        }
        for(;cnt<n;cnt++)//没弹完,继续处理
        {
            if(q2.front()>q1.front())
                q1.pop();
            else
                q2.pop();
        }
        if(flag)
        {
            if(q2.front()>q1.front())
            {
                tmp=q1.front();
                q1.pop();
            }
            else
            {
                tmp=q2.front();
                q2.pop();
            }
            ans=(double)(tmp+min(q1.front(),q2.front()))/2;
        }
        else
            ans=min(q1.front(),q2.front());
        return ans;
    }
};
View Code

 

 

posted on 2019-03-25 21:36  FTA_Macro  阅读(278)  评论(0编辑  收藏  举报

导航