Encounter-Leetcode(1)你能在你最喜欢的那天吃到你最喜欢的糖果吗?C++
Readme
题目介绍(六一吃糖果)
给你一个下标从 0 开始的正整数数组 candiesCount ,其中 candiesCount[i] 表示你拥有的第 i 类糖果的数目。同时给你一个二维数组 queries ,其中 queries[i] = [favoriteTypei, favoriteDayi, dailyCapi] 。
你按照如下规则进行一场游戏:
1.你从第 0 天开始吃糖果。
2.你在吃完 所有 第 i - 1 类糖果之前,不能吃任何一颗第 i 类糖果。
3.在吃完所有糖果之前,你必须每天至少吃一颗糖果。
请你构建一个布尔型数组 answer ,满足 answer.length == queries.length 。answer[i] 为 true 的条件是:在每天吃 不超过 dailyCapi 颗糖果的前提下,你可以在第 favoriteDayi 天吃到第 favoriteTypei 类糖果;否则 answer[i] 为 false 。注意,只要满足上面 3 条规则中的第二条规则,你就可以在同一天吃不同类型的糖果。
请你返回得到的数组 answer 。
参数范围:
1 <= candiesCount.length <= 10^5
1 <= candiesCount[i] <= 10^5
1 <= queries.length <= 10^5
queries[i].length == 3
0 <= favoriteTypei < candiesCount.length
0 <= favoriteDayi <= 10^9
1 <= dailyCapi <= 10
代码
class Solution {
public:
vector<bool> canEat(vector<int>& candiesCount, vector<vector<int>>&queries) {
vector<bool> answer(queries.size(),false);
vector<long> days = {0};
long day =0;
for(int i = 0 ; i<candiesCount.size() ; i++)
{
day = day + candiesCount[i];
days.push_back(day);
}
for(int i = 0 ; i < queries.size();i++ )
{
if(queries[i][1] < days[queries[i][0]+1] &&days[queries[i][0]]< (long) (queries[i][1]+1)*queries[i][2])
{
answer[i] = true;
}
}
return answer;
}
};
解
简单来说,你想在你最喜欢的那天吃你最喜欢的糖果。
1.几盒不同牌子的糖,每盒糖果的数量不一样。
2.你得把前面的糖果吃完才能吃后面的,但是同一天可以吃不同牌子的糖。
3.一天吃糖果不能不吃,数量还不能多于某个数字。
(六一,孩子想吃个糖怎么那么困难,叹气)
从题目的介绍来看,本身算法难度不会太高,但就是题目绕来绕去,容易绕晕。
在实际解题过程中,你会发现,每天吃的糖果只要不多于dailyCapi,不少于1就行了。没有再出现吃个糖还要再按照等差数列等奇奇怪怪的规律了。
但是这里还需要注意,计算天数是从第0天还是的,而不是通常意义上的第1天,所以假设我每天吃最少数量的1颗糖,那么在第n天,我吃的糖果是第n+1颗;假设我每天吃最多数量的dailyCap颗糖,那么在第n天,我吃到的糖果是第(n+1)*dailyCap颗糖。
那么我只要保证我最喜欢吃的糖果的前面的糖果数量小于(n+1)*dailyCap,同时这个数量+最喜欢吃的糖果的数量不能大于n+1。
根据这个思路就可以把代码打下来了。
但在实际打代码的过程中,考虑到运行速度,出现了以下几个问题。
假如每一次queries都去重新计算最喜欢的糖果前有多少颗糖果,那么显然在这个过程中,有许多计算是重复进行的。在数据集较大的情况,容易导致超时。例如,下图的数据集。
所以,算法的开头,便使用一个循环,来记录下每种最喜欢的糖果的前面糖果数量。
那么在接下来比较中,只需要调取这个数组中的值就行了。
还要要注意参数范围的限制。在 (queries[i][1]+1)*queries[i][2])的过程中,数值很有可能超过int的数据范围,所以在计算过程中,使用(long)来转换,防止溢出。