1、题干
有一棵特殊的苹果树,一连 n
天,每天都可以长出若干个苹果。在第 i
天,树上会长出 apples[i]
个苹果,这些苹果将会在 days[i]
天后(也就是说,第 i + days[i]
天时)腐烂,变得无法食用。也可能有那么几天,树上不会长出新的苹果,此时用 apples[i] == 0
且 days[i] == 0
表示。
你打算每天 最多 吃一个苹果来保证营养均衡。注意,你可以在这 n
天之后继续吃苹果。
给你两个长度为 n
的整数数组 days
和 apples
,返回你可以吃掉的苹果的最大数目。
示例 1:
输入:apples = [1,2,3,5,2], days = [3,2,1,4,2]
输出:7
解释:你可以吃掉 7 个苹果:
- 第一天,你吃掉第一天长出来的苹果。
- 第二天,你吃掉一个第二天长出来的苹果。
- 第三天,你吃掉一个第二天长出来的苹果。过了这一天,第三天长出来的苹果就已经腐烂了。
- 第四天到第七天,你吃的都是第四天长出来的苹果。
示例 2:
输入:apples = [3,0,0,0,0,2], days = [3,0,0,0,0,2]
输出:5
解释:你可以吃掉 5 个苹果:
- 第一天到第三天,你吃的都是第一天长出来的苹果。
- 第四天和第五天不吃苹果。
- 第六天和第七天,你吃的都是第六天长出来的苹果。
提示:
apples.length == n
days.length == n
1 <= n <= 2 * 104
0 <= apples[i], days[i] <= 2 * 104
- 只有在
apples[i] = 0
时,days[i] = 0
才成立
又是优先队列,JS没有优先队列,又是被折磨的一天。。。 这道题跟课程表 III类似,可以看看我之前的题解,也是计数排序
2、执行结果
3、解题思路
- 总体思路:使用贪心策略,在尚未腐烂的苹果中优先选择保质期最小的苹果。
- 关键思路:基于计数排序求保质期最小的苹果,用数组存储苹果数量和保质期,数组的下标表示保质期、值表示该日期对应的苹果数量;找保质期最小的苹果只需要以上一个最小保质期为起点,遍历数组找到下标最小且值不为0的元素。
- 时间复杂度:由于遍历的起点是上一个最小的保质期,因此总体实现出来的时间复杂度是 ,其中 是最大保质期。
下面说明代码实现细节:
- 计数排序容器记为
freshArr
,其下标表示保质期、值表示该保质期之前的苹果数量 - 最小保质期记为
minDay
,用于记录有苹果剩余的最小保质期 - 可以吃掉苹果的最大数量记为
res
,即最终结果 - 接下来以最大保质期为限制逐天遍历,天数记为
i
- 在第
i
天时,如果i
没有超过n
且过期天数大于0(i < days.length && days[i] > 0
),进行以下操作- 在计数排序容器
freshArr
中按保质期i + days[i] - 1
累加苹果数量 - 更新最小保质期
minDay = Math.min(minDay, i + days[i] - 1)
- 在计数排序容器
- 接下来只要找到有苹果剩余的最小保质期即可
- 先确保最小保质期在今天之后,即
minDay = Math.max(minDay, i)
- 然后在计数排序容器
freshArr
中遍历,找到有苹果剩余的最小保质期
- 先确保最小保质期在今天之后,即
- 接下来更新最终结果和计数排序容器
freshArr
中的苹果数量- 注意更新之前确定该保质期有苹果剩余,即
if (freshArr[minDay]) res++, freshArr[minDay]--
- 注意更新之前确定该保质期有苹果剩余,即
- 最后就得到可以吃掉苹果的最大数量
res
4、代码
var eatenApples = function (apples, days) {
let res = 0, minDay = days[0] - 1;
const freshArr = new Array(days.length).fill(0);
for (let i = 0; i < freshArr.length; i++) {
if (i < days.length && days[i] > 0) {
freshArr[i + days[i] - 1] = (freshArr[i + days[i] - 1] || 0) + apples[i];
minDay = Math.min(minDay, i + days[i] - 1);
}
minDay = Math.max(minDay, i);
while (minDay < freshArr.length && !freshArr[minDay]) minDay++;
if (freshArr[minDay]) res++, freshArr[minDay]--;
}
return res;
};