[NEO解题报告]《Leetcode》1744 -- 你能在你最喜欢的那天吃到你最喜欢的糖果吗?

1. 题目信息

1.1 题目描述

题目链接: 1744. 你能在你最喜欢的那天吃到你最喜欢的糖果吗?

给你一个下标从 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.2 测试用例

示例 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]
  • 示例 3:
[46,5,47,48,43,34,15,26,11,25,41,47]
[[11, 138, 25]]
输出: [true]
  • 提示:
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

2. 题目分析

2.1 前缀和给糖果编号后判定区间交集

咋看一下, 以为要多维dp, 仔细想想 中等难度不至于, 直接判定能否吃到指定类型的糖果, 而根据题意, 每一种糖果吃完才能吃下一种, 所以看起来就是区间判定交集的问题咯;

  • 遍历各种类型的糖果, 给每一种类型计算出一个index区间, 每个糖果相当于给一个编号;
  • 根据规则, 计算指定的那一天到来时, 可以吃到的最小糖果编号为 minIndex = days * 1 - 1, 同理, 可以吃到的最大糖果编号为 maxIndex = days * caps - 1, 注意是糖果的索引从 0 开始的, 所以要 - 1;
  • 检查两个区间, 指定类型的糖果编号区间, 按时间计算出的最小最大糖果编号区间, 判定一下两者是否有交集;

3. 代码详情

3.1 C++

3.1.1 前缀和给糖果编号后判定区间交集

// 执行用时:464 ms, 在所有 C++ 提交中击败了30.95%的用户
// 内存消耗:135.2 MB, 在所有 C++ 提交中击败了6.35%的用户
class Solution {
    using LL = long long;
public:
    vector<bool> canEat(vector<int>& candiesCount, vector<vector<int>>& queries) {
        int candyCnt = candiesCount.size();
        // 存储每个类型对应的糖果编号, [左边界, 右边界) ;
        vector<vector<LL>> typeToCount(candyCnt, vector<LL>(2));
        LL index = 0;
        LL type = 0;
        for (auto cnt: candiesCount) {
            typeToCount[type][0] = index;
            index += cnt;
            typeToCount[type++][1] = index;
        }

        vector<bool> ans;
        LL days, caps, minIndex, maxIndex;
        for (auto &q: queries) {
            type = q[0];
            days = q[1] + 1; // 下标从0开始
            caps = q[2];
            minIndex = days * 1 - 1; // 计数转换成糖果编号的下标需-1
            maxIndex = days * caps - 1;
            ans.push_back(!(maxIndex < typeToCount[type][0] || typeToCount[type][1] <= minIndex));
        }
        return ans;
    }
};

3.2 Python

4. 系列文章

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逸云沙鸥のIHave@Dream

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值