{x}
blog image

Can You Eat Your Favorite Candy on Your Favorite Day?

You are given a (0-indexed) array of positive integers candiesCount where candiesCount[i] represents the number of candies of the ith type you have. You are also given a 2D array queries where queries[i] = [favoriteTypei, favoriteDayi, dailyCapi].

You play a game with the following rules:

  • You start eating candies on day 0.
  • You cannot eat any candy of type i unless you have eaten all candies of type i - 1.
  • You must eat at least one candy per day until you have eaten all the candies.

Construct a boolean array answer such that answer.length == queries.length and answer[i] is true if you can eat a candy of type favoriteTypei on day favoriteDayi without eating more than dailyCapi candies on any day, and false otherwise. Note that you can eat different types of candy on the same day, provided that you follow rule 2.

Return the constructed array answer.

 

Example 1:

Input: candiesCount = [7,4,5,3,8], queries = [[0,2,2],[4,2,4],[2,13,1000000000]]
Output: [true,false,true]
Explanation:
1- If you eat 2 candies (type 0) on day 0 and 2 candies (type 0) on day 1, you will eat a candy of type 0 on day 2.
2- You can eat at most 4 candies each day.
   If you eat 4 candies every day, you will eat 4 candies (type 0) on day 0 and 4 candies (type 0 and type 1) on day 1.
   On day 2, you can only eat 4 candies (type 1 and type 2), so you cannot eat a candy of type 4 on day 2.
3- If you eat 1 candy each day, you will eat a candy of type 2 on day 13.

Example 2:

Input: candiesCount = [5,2,6,4,1], queries = [[3,1,2],[4,10,3],[3,10,100],[4,100,30],[1,3,1]]
Output: [false,true,true,false,false]

 

Constraints:

  • 1 <= candiesCount.length <= 105
  • 1 <= candiesCount[i] <= 105
  • 1 <= queries.length <= 105
  • queries[i].length == 3
  • 0 <= favoriteTypei < candiesCount.length
  • 0 <= favoriteDayi <= 109
  • 1 <= dailyCapi <= 109

Solution Explanation

This problem asks whether we can eat a favorite candy on a favorite day, given constraints on daily candy consumption. The core idea is to use prefix sums to efficiently determine the range of possible days a candy type can be eaten.

Algorithm:

  1. Prefix Sum Calculation: We first calculate the prefix sum of candiesCount. s[i] will store the total number of candies of types 0 to i-1. This allows us to quickly determine the total candies consumed up to a certain candy type.

  2. Query Processing: For each query [favoriteType, favoriteDay, dailyCap]:

    • We calculate the earliest day (least) we can eat a candy of favoriteType. This is simply favoriteDay.
    • We calculate the latest day (most) we can eat a candy of favoriteType. This is the total number of candies consumed before this type plus the maximum number of candies we can consume on the last day. Thus most = (favoriteDay + 1) * dailyCap.
    • We check if it is possible to eat a candy of type favoriteType on day favoriteDay. This is true if the total number of candies of types 0 to favoriteType -1 is less than favoriteDay + 1 ( meaning that all candies of the previous types are consumed before) and most is greater than the total candies of types 0 to favoriteType. If this holds true, we can eat the candy on that day; otherwise we can't.

Time and Space Complexity Analysis:

  • Time Complexity: O(M + N), where N is the length of candiesCount and M is the length of queries. Calculating the prefix sum takes O(N) time, and processing each query takes O(1) time. Therefore, the overall time complexity is dominated by the sum of these two operations.

  • Space Complexity: O(N), where N is the length of candiesCount. We use a prefix sum array of size N + 1 to store the prefix sums. The space used by other variables is constant.

Code Examples (with detailed comments):

Python:

from itertools import accumulate
 
class Solution:
    def canEat(self, candiesCount: List[int], queries: List[List[int]]) -> List[bool]:
        # Calculate prefix sums
        prefix_sums = list(accumulate(candiesCount, initial=0))  
        
        result = []
        for fav_type, fav_day, daily_cap in queries:
            # Earliest day to eat candy of fav_type
            least_day = fav_day  
            # Latest day to eat candy of fav_type
            latest_day = (fav_day + 1) * daily_cap  
            
            # Check if we can eat the candy on the favorite day
            can_eat = (prefix_sums[fav_type] < latest_day +1 ) and (prefix_sums[fav_type+1] > least_day)
            result.append(can_eat)
            
        return result

Java:

import java.util.Arrays;
 
class Solution {
    public boolean[] canEat(int[] candiesCount, int[][] queries) {
        long[] prefixSums = new long[candiesCount.length + 1];
        for (int i = 0; i < candiesCount.length; ++i) {
            prefixSums[i + 1] = prefixSums[i] + candiesCount[i];
        }
 
        boolean[] result = new boolean[queries.length];
        for (int i = 0; i < queries.length; ++i) {
            int favType = queries[i][0];
            long favDay = queries[i][1];
            long dailyCap = queries[i][2];
            
            long leastDay = favDay;
            long latestDay = (favDay + 1) * dailyCap;
            
            result[i] = (prefixSums[favType + 1] > leastDay) && (prefixSums[favType] < latestDay) ;
        }
        return result;
    }
}

The other languages (C++, Go) would follow a similar structure, using prefix sums to efficiently solve the problem. The key is understanding the constraints and translating them into range checks using prefix sums.