跳过正文

24日 No.1705 吃苹果的最大数目

·1191 字·3 分钟
曙光磁铁
作者
曙光磁铁

有一棵特殊的苹果树,一连 n 天,每天都可以长出若干个苹果。在第 i 天,树上会长出 apples[i] 个苹果,这些苹果将会在 days[i] 天后(也就是说,第 i + days[i] 天时)腐烂,变得无法食用。也可能有那么几天,树上不会长出新的苹果,此时用 apples[i] == 0days[i] == 0 表示。

你打算每天 最多 吃一个苹果来保证营养均衡。注意,你可以在这 n 天之后继续吃苹果。

给你两个长度为 n 的整数数组 daysapples ,返回你可以吃掉的苹果的最大数目

 

示例 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 才成立

思路分析
#

首先看到吃苹果的数量最多只能一天一个,我们可以得出结论,每天都应该吃今天之后最早过期的那个苹果,这种策略在生活中也非常常见,大家总是喜欢先吃(自己拥有的)快到期的食物,这样可以尽可能多的减少浪费(也就是多吃)。
在这种策略的驱使下,我们可以使用一个数组rots作为苹果过期的标识,然后再使用一个eatId作为当前可以吃的最早腐烂的苹果腐烂时的天数。在这种情况下,我们在每一天收获新的苹果的时候只需要做如下几件事:(假设当前是第i天,数组下标均默认从1开始,与题目描述中的相同)

  • 首先确保eatId,也就是当前能吃的苹果的最小天数一定小于当前的天数
  • 然后再看看今天收货的苹果,假设今天获得a个苹果,n天后腐烂,那么我们就将其添加到rots中,也就是使得rots[i + n - 1] += a,因为在第i+n天我们就不能吃这批苹果了,所以能吃这批苹果的最后一天就是i+n-1的时候。
  • 最后开始选择能吃的苹果,如果eatId大于今天新到的一批苹果腐烂的天数,那么我们就将eatId设置为今天新到的腐烂时间,也就是说,如果今天新来苹果烂的早,我们就先吃它
  • 在选择了能吃的苹果之后(在这个地方,如果rots[eatId]等于0,说明当前选择的天数已经没有待吃的苹果了,我们就必须要让eatId加到有苹果的地方,因为我们假设的是eatId是距离今天最近的腐烂苹果的天数,所以只能向后选择),就使答案加一,并且使得rots[eatId] -= 1。如果没有剩余的苹果,就啥都不吃

Rust代码
#

impl Solution {
    pub fn eaten_apples(apples: Vec<i32>, days: Vec<i32>) -> i32 {
        let mut rots = [0; 40005];
        let mut eatId = 0;
        let mut res = 0;
        for index in 1..40003 {
            eatId = eatId.max(index);
            if index <= apples.len() && apples[index - 1] != 0 {
                rots[index - 1 + days[index - 1] as usize] += apples[index - 1];
                eatId = eatId.min(index - 1 + days[index - 1] as usize);
            }
            while rots[eatId] == 0 && eatId < 40002 {
                eatId += 1;
            }
            if eatId != 40002 {
                rots[eatId] -= 1;
                res += 1;
            }
        }
        res
    }
}