LintCode 数飞机的两种解法

给出飞机的起飞和降落时间的列表,用 interval 序列表示. 请计算出天上同时最多有多少架飞机?
看到题目时,先画了一个表格,如图1,然后在想要若要知道同时最多有多少架飞机在天上飞,那我得知道任意一时刻天上的飞机数啊,于是我将表1转成了时间轴直方图的样子,如图2.

图1
图2
从上图可以很快的想出一个解决方案,只需要采用一个数组就可以记录下任一时刻正在飞行的飞机数了,如何记录呢,将正在飞行的飞机时间段对应到数组元素中,然后相应元素加1,最后找出最大的数组元素即可。代码如下:

class Solution {
public:
    /*
     * @param airplanes: An interval array
     * @return: Count of airplanes are in the sky.
     */
    int countOfAirplanes(vector<Interval> &airplanes) {
        // write your code here
        int nLen = airplanes.size();
        if ( nLen <= 0 )
            return 0;
        int nTimeMin = 0xFF, nTimeMax = 0;
        for ( int i = 0; i < nLen; i++ )
        {
            if ( airplanes[i].start < nTimeMin )
            {
                nTimeMin = airplanes[i].start;
            }
            if ( airplanes[i].end > nTimeMax )
            {
                nTimeMax = airplanes[i].end;
            }
        }
        int nSize = nTimeMax - nTimeMin + 1;
        int* nRecord = new int[nSize];
        memset((char*)nRecord, 0, sizeof(int) * nSize);

        int nMaxPlane =0;
        for ( int i = 0; i < nLen; i++ )
        {
            for ( int j = airplanes[i].start; j < airplanes[i].end; j++ )
            {
                nRecord[j - nTimeMin]++;
                if ( nRecord[j - nTimeMin] > nMaxPlane )
                {
                    nMaxPlane = nRecord[j - nTimeMin];
                }
            }

        }
        return nMaxPlane;
    }
};
分析下复杂度,空间负责度为O(M),M为最晚飞行时间减去最早飞行时间;时间复制度为O(K*N), K为平均飞行时间,N为飞机数量。空间复杂度还蛮高的,有没有办法降低呢。
通过观察,发现飞行的飞机数量只在飞机起飞和降落的时刻发生改变,因此只需要记录起飞时刻和降落时刻飞行飞机数的改变量就可以了。如1时刻,有一个飞机起飞,飞行数+1,2时刻有一个飞机起飞,飞行数+1,3时刻有一个飞机数降落,飞行数-1,以此类推。那么如何得到每一时刻飞机的改变数呢,只需提前遍历一下就好了,具体代码如下:
class Solution {
public:
    /*
     * @param airplanes: An interval array
     * @return: Count of airplanes are in the sky.
     */
    int countOfAirplanes(vector<Interval> &airplanes) {
        // write your code here
        int nLen = airplanes.size();
        if ( nLen <= 0 )
            return 0;
        int nTimeMin = 0xFF, nTimeMax = 0;
        for ( int i = 0; i < nLen; i++ )
        {
            if ( airplanes[i].start < nTimeMin )
            {
                nTimeMin = airplanes[i].start;
            }
            if ( airplanes[i].end > nTimeMax )
            {
                nTimeMax = airplanes[i].end;
            }
        }
        int nSize = nTimeMax - nTimeMin + 1;
        int* nRecord = new int[nSize];
        memset((char*)nRecord, 0, sizeof(int) * nSize);

        for ( int i = 0; i < nLen; i++ )
        {
           int kStart = airplanes[i].start - nTimeMin;
           int kEnd = airplanes[i].end - nTimeMin;
           nRecord[kEnd]--;
           nRecord[kStart]++;
        }
        int nMaxPlane = 0;
        int nCurPlane = 0;
        for ( int i = 0; i < nSize; i++ )
        {
            nCurPlane += nRecord[i];
            if (nCurPlane > nMaxPlane)
            {
                nMaxPlane = nCurPlane;
            }
        }
        return nMaxPlane;
    }
};
空间复杂度还是一样,时间复杂度为O(M) + O(N), M为最晚飞行时间减去最早飞行时间, N为飞机数量。
这是我目前想到的两种方案,不知是否还有更优的解决方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值