每日一题 ~继续打卡
闲话不多说,直接上图!今天是六一儿童节,每日一题要我们来吃糖hhh.
起初看了好多遍题干,感觉还是很懵逼,他要我们干什么…?
后来买了包糖边吃边思索后有了大体方向(哈哈感谢QQ糖)
我大致说下:
1:每天至少吃一颗糖
2:queries这里面的东西要一组一组去看,是相互独立的,每一组对应一个布尔类型的answer。
3:你需要在指定日期(favoriteDay)吃到指定类型的糖。
那么!!!关键就在于如何在指定日期吃到指定的糖呢,我要往哪思考?
自己吃糖是一回事,吃到指定类型的糖又是一回事,如何使他俩产生交集?这个是解题的关键!
- dailyCap是规定的每天吃糖上限,而题干中又要求每天至少一颗糖。
那么自己吃糖的区间出来了[favoriteDay +1, (favoriteDay + 1)*dailyCap]
那么指定糖的区间又怎么去表示呢,题干只给了每种糖的数量与类型(索引)的对应,那么用区间表示每种指定的糖就需要用到数组的前缀了
不废话了,上代码了
class Solution {
public boolean[] canEat(int[] candiesCount, int[][] queries) {
//前缀和
int len = candiesCount.length;
long[] sum = new long[len+1];
for(int i = 0;i < len;i++){
sum[i+1] = sum[i] + candiesCount[i];
}
int n = queries.length;
boolean[] ans = new boolean[n];
int[] nums = new int[n];
//queries[i] = [favoriteType, favoriteDay, dailyCap]
for(int t = 0;t < n;t++){
nums = queries[t];
int favoriteType = nums[0],favoriteDay = nums[1],dailyCap = nums[2];
//开始构造两个集合
//第一个集合(自己吃的糖)
long a = favoriteDay + 1;//自己吃糖的最小数量,因为是从0天开始所以加一
long b = (long)(favoriteDay + 1)*dailyCap;//自己吃糖的最大数量
//第二个集合 (需要吃到糖的数量的范围)
long c = favoriteType == 0 ? 1 : sum[favoriteType] + 1;//左边界 注意sum索引要+1
long d = sum[favoriteType+1];//右边界 同理
if((a > d)||(c > b)){
ans[t] = false;
}else{ans[t] = true;}
}
return ans;
}
}
这里要注意的是,题目给的queri是二维数组,我们要把他拆了一个一个来判断。
要吃到指定类型的糖就用它对应的索引去表示,而且sum就是前缀和。
注意在求前缀和时sum的长度是 len+1,这也代表着后面的是sum[favoriteType]和sum[favoriteType+1],而不是sum[favoriteType-1]和sum[favoriteType],可以理解下…
一旦自己吃的糖与目标类型的糖有了交集就代表吃到了
为了代码的可读性,这里取补集更省劲。
除了这两种情况,其他的全为true(意味着[a,b]区间与[c,d]区间有了交集)
最后再补充一点:用int类型会溢出…这就是为什么第一次会WA…
如果觉得我的解析对您有帮助,不妨点个小赞~嘿嘿
如有疑惑可以在评论区提出,看到会及时解答!
六一快乐!