前缀和题看了题解https://leetcode.cn/problems/maximum-population-year/

给定一个表示出生和死亡年份的二维数组,计算每个年份的人口并找到人口最多且出现最早的年份。利用公交车模型的思想简化计算过程,通过前缀和优化时间复杂度。
摘要由CSDN通过智能技术生成

给你一个二维整数数组 logs ,其中每个 logs[i] = [birthi, deathi] 表示第 i 个人的出生和死亡年份。

年份 x 的 人口 定义为这一年期间活着的人的数目。第 i 个人被计入年份 x 的人口需要满足:x 在闭区间 [birthi, deathi - 1] 内。注意,人不应当计入他们死亡当年的人口中。

返回 人口最多 且 最早 的年份。

示例 1:

输入:logs = [[1993,1999],[2000,2010]]
输出:1993
解释:人口最多为 1 ,而 1993 是人口为 1 的最早年份。

示例 2:

输入:logs = [[1950,1961],[1960,1971],[1970,1981]]
输出:1960
解释: 
人口最多为 2 ,分别出现在 1960 和 1970 。
其中最早年份是 1960 。

提示:

  • 1 <= logs.length <= 100
  • 1950 <= birthi < deathi <= 2050

知识前置:说是有一个模型叫作公交车模型,这个内容是什么呢。我结合自己的理解来说明一下。假如公交车每次发站都是乘客的人数为0,每次到一个站都会有乘客上下车,那么在当前站公交车的人数就是上车人数-下车人数加上上一站的人数,注意,这个变化量有可能是负的。那么我们可以说当前人数就是变化的人数加上上一站的人数。也就是passenger[i] = passenger[i- 1] + passengerDiff[i],passengerDiff[i] = 变化的人数。

这个知识有什么用呢,在我们这道题目,这个变化的人数怎么算呢?其实就是根据二维数组来计算的,在这个year数组,它其实就是一个差分数组,我们在对应的出生日期加一,死亡日期减一,然后对差分数组做一次前缀和还原成原数组。其实我们用的这个year数组就相当于变化的人数。所以呢, 我们要求的每一年的人数=year[i]+这一年人数的当前量,也就是说,我设这个人数的数组为a,那么通式是a[i] = a[i-1] + year[i]+0;但是,这个时间复杂度是6ms,正常来说是不能通过的,那么我们怎么简化这个过程。其实,只要将这个变化的数组当成原数组就可以了,也就是year[i]  += year[i-1],因为本身应该是0+year[i-1],为什么是0,因为初始化是0,这里就可以直接简化了。

代码:

int maximumPopulation(int** logs, int logsSize, int* logsColSize) {

    int year[2051]={0};//初始化为各个年份没有死亡和出生人数

    int max = 0;

    for(int i = 0;i < logsSize;i++){

        year[logs[i][0]]++;//出生的年份人数加1

        year[logs[i][1]]--;//从死亡年份后(包括死亡年份)减一,等会前缀和的时候可以消除对后面的影响

    }

    for(int i = 1950;i <= 2050;i++){

        year[i] += year[i-1];

        max = year[i] > year[max]?i:max;

    }

    return max;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值