改良空间复杂度的差分数组
今天的leetcode每日一题是一道关于差分数组的困难题,其实说是困难题目,但是如果之前知道差分数组的思想,这个题目也不难,甚至是非常明显的差分数组,只不过使用最基础的差分数组的写法在空间上比较浪费,所以需要稍微改良一下。
题目描述如下:
给你一个下标从 0 开始的二维整数数组 flowers ,其中 flowers[i] = [,] 表示第 i 朵花的 花期 从 到 (都 包含)。同时给你一个下标从 0 开始大小为 n 的整数数组 people ,people[i] 是第 i 个人来看花的时间。
请你返回一个大小为 n 的整数数组 answer ,其中 answer[i]是第 i 个人到达时在花期内花的数目 。
基本的差分数组思想
这个题目一眼看过去,采用最基础的差分数组的写法,我们就需要声明一个长度为n+1(n为所有flowers中end值的最大值)的数组count,并且每一项都初始化为0,然后遍历flowers数组,对于每一对,我们让,最后在计算每个people的时候,计算差分数组的前缀和即可
但是这个题目的数据有如下限制:
1 | 1 <= flowers.length <= 5 * 104 |
改良的差分数组
如果是这样,我们声明的数组就可能很大,所以我们需要考虑是否能够优化这个差分数组的存储。
我们回过头来仔细观察这个差分数组,会发现,其实我们没有必要存储那些从头到尾都没有变化(即flowers数组中从来没出现该项的下标)的项,所以我们可以考虑用map来存储差分数组中变化的项,这样就能节省大量空间。
其次,在对差分数组求前缀和的过程中,我们可以保存下来累计的结果,即先计算出先到的人能看到的花朵数,然后存储下来,再继续计算前缀和到下一个人来的时间点。
代码如下:
1 | var fullBloomFlowers = function(flowers, people) { |
其他思路
第 i 到达的时间为 people[i],假设在 people[i] 时间点之前花开的数目为 x,在 people[i] 时间之前花谢的数目为 y,则在 people[i] 时间点还处于开花状态的数目等于 x−y。我们只需要找到 start≤people[i] 的花朵数目,减去 end<people[i] 的花朵数目即为 people[i] 时间点可以看到花开的数目。 根据以上分析,我们可以单独统计起始时间 start 与结束 end,利用二分查找即可快速查找结果。
首先需要将所有的起始时间 start、结束时间 end 按照从早到晚进行排序;
设第 i 个人到达的时间 people[i],利用二分查找找到≤people[i] 的花朵数目为 x,利用二分查找找到<people[i] 的花朵数目为 y,则第 i 个人可以看到的花朵数目为 x−y;
依次遍历并统计每个人的查询结果即可;