【LeetCode】1744. 你能在你最喜欢的那天吃到你最喜欢的糖果吗?

148 阅读3分钟

你能在你最喜欢的那天吃到你最喜欢的糖果吗?

给你一个下标从0开始的正整数数组 candiesCount,其中candiesCount[i] 表示你拥有的第i类糖果的数目。同时给你一个二维数组queries,其中queries[i] = [favoriteTypei, favoriteDayi, dailyCapi] 。

你按照如下规则进行一场游戏:

  • 你从第0天开始吃糖果。
  • 你在吃完所有第i-1类糖果之前,不能吃任何一颗第i类糖果。
  • 在吃完所有糖果之前,你必须每天至少吃一颗糖果。

请你构建一个布尔型数组answer,满足answer.length==queries.length。answer[i]为true的条件是:在每天吃不超过dailyCapi颗糖果的前提下,你可以在第favoriteDayi天吃到第favoriteTypei类糖果;否则answer[i]为false。注意,只要满足上面3条规则中的第二条规则,你就可以在同一天吃不同类型的糖果。

请你返回得到的数组answer 。

示例1

输入:candiesCount = [7,4,5,3,8], queries = [[0,2,2],[4,2,4],[2,13,1000000000]]
输出:[true,false,true]
提示:
1-在第0天吃2颗糖果(类型0),第1天吃2颗糖果(类型0),第2天你可以吃到类型0的糖果。
2- 每天你最多吃4颗糖果。即使第0天吃4颗糖果(类型0),第1天吃4颗糖果(类型0和类型1),你也没办法在第2天吃到类型4的糖果。换言之,你没法在每天吃4颗糖果的限制下在第2天吃到第4类糖果。
3- 如果你每天吃1颗糖果,你可以在第13天吃到类型2的糖果。

示例2

输入:candiesCount = [5,2,6,4,1], queries = [[3,1,2],[4,10,3],[3,10,100],[4,100,30],[1,3,1]]
输出:[false,true,true,false,false]

思路

  • 本题使用前缀和的思想求解。可以得出:
dp[i+1]=dp[i]+candiesCount[i]

其中,dp[i+1]表示第0到i类糖果的数量和。

  • 题目中可以根据每天至少吃一颗糖和最多吃dailyCapi颗糖果定义上下边界。那么只要第favoriteTypei类糖果的数量满足在上下边界范围之内,则可以返回true,否则返回false。
  • 需要注意的陷阱是:我们是从第0天开始吃糖果。
  • 因此对于第i个询问(favoriteTypei, favoriteDayi, dailyCapi),我们吃的糖果数量需要落在区间:
  • 更清晰的表达如解法二。
[(favoriteDayi+1)*1,(favoriteDayi+1)*dailyCapi]
  • 那么只要在上述区间内包含了favoriteTypei一颗糖就满足要求了。也就说:
dp[favoriteTypei+1]>(favoriteDayi+1)*1且dp[favoriteTypei]<(favoriteDayi+1)*dailyCapi

解法一

func canEat(candiesCount []int, queries [][]int) []bool {
    res:=make([]bool,len(queries))
    dp:=make([]int,len(candiesCount)+1)
    for i:=0;i<len(candiesCount);i++{
        dp[i+1]=dp[i]+candiesCount[i]
    }
    for i,v:=range queries{
        favoriteType,favoriteDay,dailyCap:=v[0],v[1],v[2]
        left:=favoriteDay*1
        right:=(favoriteDay+1)*dailyCap
        if left<dp[favoriteType+1]&&right>dp[favoriteType]{
            res[i]=true
        }else{
            res[i]=false
        }
    }
    return res
}

解法二

func canEat(candiesCount []int, queries [][]int) []bool {
    res:=make([]bool,len(queries))
    dp:=make([]int,len(candiesCount)+1)
    for i:=0;i<len(candiesCount);i++{
        dp[i+1]=dp[i]+candiesCount[i]
    }
    for i,v:=range queries{
        favoriteType,favoriteDay,dailyCap:=v[0],v[1],v[2]
        maxDays:=(dp[favoriteType+1])/1-1
        minDays:=(dp[favoriteType])/dailyCap
        if minDays<=favoriteDay&&favoriteDay<=maxDays{
            res[i]=true
        }else{
            res[i]=false
        }
    }
    return res
}