当前位置: 首页 > news >正文

每日算法刷题Day39 6.26:leetcode前缀和2道题,用时1h20min

8. 2055.蜡烛之间的盘子(中等,学习替换查询区间)

2055. 蜡烛之间的盘子 - 力扣(LeetCode)

思想

1.给你一个长桌子,桌子上盘子和蜡烛排成一列。给你一个下标从 0 开始的字符串 s ,它只包含字符 '*''|' ,其中 '*' 表示一个 盘子'|' 表示一支 蜡烛
同时给你一个下标从 0 开始的二维整数数组 queries ,其中 queries[i] = [lefti, righti] 表示 子字符串 s[lefti...righti]包含左右端点的字符)。对于每个查询,你需要找到 子字符串中两支蜡烛之间 的盘子的 数目 。如果一个盘子在 子字符串中 左边和右边 至少有一支蜡烛,那么这个盘子满足在 两支蜡烛之间

  • 比方说,s = "||**||**|*" ,查询 [3, 8] ,表示的是子字符串 "*||**_**_**|" 。子字符串中在两支蜡烛之间的盘子数目为 2 ,子字符串中右边两个盘子在它们左边和右边 至少有一支蜡烛。
    请你返回一个整数数组 answer ,其中 answer[i] 是第 i 个查询的答案。
    2.这题能想到用前缀和,但是不能简单地计算[querie[0],querie[1]]的区间和,因为|*|*|例子中[0,3]|*|*的有效*只有1个,而如果按照简单前缀和的逻辑答案为2,所以这个区间不对,要更换更小的区间。因为是考虑两个蜡烛内的盘子数,所以可以左端点querie[0]找它右边最近的蜡烛位置,右端点找它左边最近的蜡烛位置,从而替换原始查找区间,变成[rightId[querie[0]],leftId[querie[1]]],而找左边最近的蜡烛位置可以在遍历时判断赋值更新
代码

c++:

class Solution {
public:vector<int> platesBetweenCandles(string s, vector<vector<int>>& queries) {int n = s.size();vector<int> sum(n + 1, 0);vector<int> leftId(n);  // 左边最近蜡烛位置vector<int> rightId(n); // 右边最近蜡烛位置sum[0] = 0;int preId = -1;for (int i = 0; i < n; ++i) {sum[i + 1] = sum[i];if (s[i] == '|')preId = i; // 边枚举边更新else++sum[i + 1];leftId[i] = preId; // 边枚举边赋值}int lastId = n;for (int i = n - 1; i >= 0; --i) {if (s[i] == '|')lastId = i;rightId[i] = lastId;}vector<int> res;for (auto& querie : queries) {// 用[rightId[querie[0]],leftId[querie[1]]]来替代[querie[0],querie[1]]区间int left = rightId[querie[0]], right = leftId[querie[1]];if (left < right)res.emplace_back(sum[right + 1] - sum[left]);elseres.emplace_back(0);}return res;}
};
9. 1744.你能在你最喜欢的那天吃到你最喜欢的糖果吗?(中等,想法没错,范围再考虑清楚)

1744. 你能在你最喜欢的那天吃到你最喜欢的糖果吗? - 力扣(LeetCode)

思想

1.给你一个下标从 0 开始的正整数数组 candiesCount ,其中 candiesCount[i] 表示你拥有的第 i 类糖果的数目。同时给你一个二维数组 queries ,其中 queries[i] = [favoriteTypei, favoriteDayi, dailyCapi]
你按照如下规则进行一场游戏:

  • 你从第 **0** 天开始吃糖果。
  • 你在吃完 所有i - 1 类糖果之前,不能 吃任何一颗第 i 类糖果。
  • 在吃完所有糖果之前,你必须每天 至少一颗 糖果。
    请你构建一个布尔型数组 answer ,用以给出 queries 中每一项的对应答案。此数组满足:
  • answer.length == queries.lengthanswer[i]queries[i] 的答案。
  • answer[i]true 的条件是:在每天吃 不超过 dailyCapi 颗糖果的前提下,你可以在第 favoriteDayi 天吃到第 favoriteTypei 类糖果;否则 answer[i]false
    注意,只要满足上面 3 条规则中的第二条规则,你就可以在同一天吃不同类型的糖果。
    请你返回得到的数组 answer
    2.因为每个查询是独立的,且每个查询得到一个吃的糖果范围:[1*(favoriteDayi+1),dailyCapi*(favoriteDayi+1)](注意从0开始,且那一天也要算上,所以要加1,考虑清楚),而要吃到第favoriteTypei糖果的范围为[s[favoriteTypei-1+1]+1,s[favoriteTypei+1](因为定义的前缀和是要加上1的),这边有两个细节要考虑清楚才不会出错.两个区间有交集则说明可以
代码

c++:

class Solution {
public:vector<bool> canEat(vector<int>& candiesCount,vector<vector<int>>& queries) {int n = candiesCount.size();vector<long long> s(n + 2, 0);s[0] = 0;s[n + 1] = LONG_MAX;for (int i = 0; i < n; ++i)s[i + 1] = s[i] + candiesCount[i];vector<bool> res;for (auto& querie : queries) {// day要+1,把那天吃的糖果也考虑到,所以吃的糖果范围为[1*day,cap*day]int type = querie[0], day = querie[1] + 1, cap = querie[2];// type类糖果范围为:(s[type-1]+1,s[type]),但是s还要加个1if ((1LL * cap * day < s[type - 1 + 1] + 1) ||(1LL * 1 * day > s[type + 1]))res.emplace_back(false);elseres.emplace_back(true);}return res;}
};

相关文章:

  • 009 【入门】单双链表及其反转-堆栈诠释
  • 记一次生产Redis集群宕机恢复过程
  • JDeli:Java 图像处理领域中的 Aspose 替代方案
  • ubuntu18.04安装 gcc 9以及2019版本tbb
  • 基于ubuntu 22.04环境安装NEURON仿真器
  • AcWing--数据结构(二)
  • Redis 单线程的“天花板”与集群的必要性
  • 学习记录:DAY34
  • Windows家庭版安装docker
  • SOCKSv5 协议通信的完整阶段与报文格式详解
  • Linux常用指令大全
  • 【编译原理】第九章 习题
  • 医院信息化建设的要点
  • 东方通密码重置指南:快速解决
  • 【C++】atoi和std::stoi
  • 大数据在UI前端的应用深化研究:用户情感分析的探索与实践
  • Go中interface接口的设计理念
  • 【雅思播客013】what do you do
  • 黑马JVM解析笔记(五):深入理解Java字节码执行机制
  • 1 Studying《Is Parallel Programming Hard》6-9