打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
力扣266场周赛
1 问题
5918. 统计字符串中的元音子字符串
子字符串 是字符串中的一个连续(非空)的字符序列。元音子字符串 是 仅 由元音('a'、'e'、'i'、'o' 和 'u')组成的一个子字符串,且必须包含 全部五种 元音。给你一个字符串 word ,统计并返回 word 中 元音子字符串的数目 。
题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-vowel-substrings-of-a-string
示例:
输入:word = "aeiouu"
输出:2
解释:下面列出 word 中的元音子字符串(斜体加粗部分):
- "aeiouu"
- "aeiouu"
解析:该题题意就是找到由元音子字符串的个数,由于给出的数据范围n <= 100很小,所以可以直接采用暴搜来解决,遍历所有的子字符串,如果满足题意就直接在结果上加一;此处采用双for来遍历所有的子字符串。时间复杂度为O(n^2);
代码
const int N = 27;
class Solution {
public:
bool snt[N], cnt[N];
int countVowelSubstrings(string word) {
char bu[5] = {'a', 'e', 'i', 'o', 'u'};
int n = word.size(), res = 0;
for (char c: bu) {
int t = c - 'a';
snt[t] = true;
}
for (int i = 0; i < n; i ++){
int t = word[i] - 'a';
if (!snt[t]) continue;
int num = 0, p = 0;
memset(cnt, 0, sizeof cnt);
for (int j = i; j < n; j ++) {
int k = word[j] - 'a';
if (!snt[k]) break;
if (!cnt[k]) {
cnt[k] = true;
p ++;
}
if (p >= 5) num ++;
}
res += num;
}
return res;
}
};
5919. 所有子字符串中的元音
给你一个字符串 word ,返回 word 的所有子字符串中 元音的总数 ,元音是指 'a'、'e'、'i'、'o' 和 'u' 。子字符串 是字符串中一个连续(非空)的字符序列。注意:由于对 word 长度的限制比较宽松,答案可能超过有符号 32 位整数的范围。计算时需当心。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/vowels-of-all-substrings
示例;
输入:word = "aba"
输出:6
解释:所有子字符串是:"a"、"ab"、"aba"、"b"、"ba" 和 "a" 。- "b" 中有 0 个元音- "a"、"ab"、"ba" 和 "a" 每个都有 1 个元音- "aba" 中有 2 个元音,因此,元音总数 = 0 + 1 + 1 + 1 + 1 + 2 = 6 。
解析:此题与第一题有些类似,不过该题是要求出包含元音子字符串的元音的个数总和,此题不可以采用暴搜,数据范围为1e5,否则会tle;不过此题可以反过来想,要求我们找到包含元音子字符串, 那么我们可以找到每一个元音字符,然后求出它所能构成的子字符串的数量即可。
例如 babe 找到元音字符’a’、’e’ 分别位于1、3的位置;对于’a’来说,他所能构成的包含自身的子字符串的数量为,a左边的个数乘以右边个数!解释:左边部分时即为b, 右边部分为be,而右边部分可以选0个、1个、2个  (注意题目中要求为连续的子字符串) 所以有三种,同理左边部分有两种,所有总共包含a的子字符串数量为2*3 = 6种。
代码
class Solution {
public:
typedef long long LL;
long long countVowels(string word) {
LL res = 0ll;
int n = word.size();
for (int i = 0; i < n; i ++ ) {
if (word[i] == 'a' || word[i] == 'e' || word[i] == 'i' || word[i] == 'o' || word[i] == 'u') {
res = res + (LL)(i + 1) * (n - i);
}
}
return res;
}
};
5920. 分配给商店的最多商品的最小值
给你一个整数 n ,表示有 n 间零售商店。总共有 m 种产品,每种产品的数目用一个下标从 0 开始的整数数组 quantities 表示,其中 quantities[i] 表示第 i 种商品的数目。
你需要将 所有商品 分配到零售商店,并遵守这些规则:
一间商店 至多 只能有 一种商品 ,但一间商店拥有的商品数目可以为 任意 件。
分配后,每间商店都会被分配一定数目的商品(可能为 0 件)。用 x 表示所有商店中分配商品数目的最大值,你希望 x 越小越好。也就是说,你想 最小化 分配给任意商店商品数目的 最大值 。请你返回最小的可能的 x 。
来源:力扣(LeetCode)
链接:
https://leetcode-cn.com/problems/minimized-maximum-of-products-distributed-to-any-store
示例;
输入:n = 6, quantities = [11,6]
输出:3
解释: 一种最优方案为:- 11 件种类为 0 的商品被分配到前 4 间商店,分配数目分别为:2,3,3,3 。- 6 件种类为 1 的商品被分配到另外 2 间商店,配数目分别为:3,3 。分配给所有商店的最大商品数目为 max(2, 3, 3, 3, 3, 3) = 3 。
来源:力扣(LeetCode)
链接:
https://leetcode-cn.com/problems/minimized-maximum-of-products-distributed-to-any-store
解析:此题的题意为给出quantities.size()个数,每一个数可以平摊到n个商店中的一些商店(或者全部)当中(解释:如果k平摊到m个商店当中, 那么每个商店的取值就为m/k或者ceil(m/k) ),但是每一个商店只能平摊quantities的某一个数,最后求最大值的最小;
此题有两种思考方式:
第一种就是贪心去模拟,每一次贪心的取最大的quantities[i],然后分摊商店的个数+1,进行分摊操作。其实也就是去模拟整个过程,但是此题模拟的时间复杂度很高,很容易超时。
第二种二分,可以注意到该题的数据范围为1 <= quantities[i] <= 1e5,所以我们去枚举所有的分摊操作的可能性,就是每一个商店分摊的数量,最后判断每一个quantities[i]全部分配完毕后会不会超过n个商店的个数。此处枚举可以采用二分进行枚举; 时间复杂度为O(mlog1e5).
代码
const int N = 100010;
class Solution {
public:
int m;
bool check(vector<int>& quantities, int k, int n){
int num = 0;
for (int i = 0; i < m; i ++) {
num += ceil((double)quantities[i]/k);
if (num > n) return false;
}
return true;
}
int minimizedMaximum(int n, vector<int>& quantities) {
m = quantities.size();
int l = 1, r = 100000;
while(l < r) {
int mid = l + r >> 1;
if (check(quantities, mid, n)) r = mid;
else l = mid + 1;
}
return r;
}
};
5921. 最大化一张图中的路径价值
给你一张 无向 图,图中有 n 个节点,节点编号从 0 到 n - 1 (都包括)。同时给你一个下标从 0 开始的整数数组 values ,其中 values[i] 是第 i 个节点的 价值 。同时给你一个下标从 0 开始的二维整数数组 edges ,其中 edges[j] = [uj, vj, timej] 表示节点 uj 和 vj 之间有一条需要 timej 秒才能通过的无向边。最后,给你一个整数 maxTime 。合法路径 指的是图中任意一条从节点 0 开始,最终回到节点 0 ,且花费的总时间 不超过 maxTime 秒的一条路径。你可以访问一个节点任意次。一条合法路径的 价值 定义为路径中 不同节点 的价值 之和 (每个节点的价值 至多 算入价值总和中一次)。请你返回一条合法路径的 最大 价值。注意:每个节点 至多 有 四条 边与之相连。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-path-quality-of-a-graph
示例;
输入:values = [0,32,10,43], edges = [[0,1,10],[1,2,15],[0,3,10]], maxTime = 49
输出:75
解释:一条可能的路径为:0 -> 1 -> 0 -> 3 -> 0 。总花费时间为 10 + 10 + 10 + 10 = 40 <= 49 。访问过的节点为 0 ,1 和 3 ,最大路径价值为 0 + 32 + 43 = 75 。
解析:该题就是一个一般的图论问题,从0出发最终回到0,且途径的时间不超过给出的最大时间限制;此题注意到10 <= timej, maxTime <= 100、每个节点至多有四条边;所以说步数不会超过10次,采用深搜可以解决此题,不用担心会超时;用邻接表记录每一条边、时间、价值三种数据,然后dfs遍历所有可能,记录从0出发最终回到0点的最大价值。
代码
const int N = 4010, M = 1010;
class Solution {
public:
int e[N], ne[N], w[N], idx, h[M], Times, res;
bool snt[N];
void add(int a, int b, int c){
e[idx] = b;
ne[idx] = h[a];
w[idx] = c;
h[a] = idx ++;
}
void dfs(vector<int>& values, int time, int val, int value){
if (time >= Times) {
if (time == Times && val == 0) res = max(res, value);
return;
}
if (val == 0) res = max(res, value);
int p = values[val];
values[val] = 0;
for (int i = h[val]; i != -1; i = ne[i]) {
int k = e[i], t = time + w[i];
dfs(values, t, k, value + values[k]);
}
values[val] = p;
}
int maximalPathQuality(vector<int>& values, vector<vector<int>>& edges, int maxTime) {
Times = maxTime;
memset(h, -1, sizeof h);
for (auto ed: edges) {
int s = ed[0], d = ed[1], c = ed[2];
add(s, d, c);
add(d, s, c);
}
dfs(values, 0, 0, values[0]);
return  res;
}
};
2 总结
本博客是力扣266场周赛的题解,如果存在不懂的地方可以在评论区提出,这里会耐心解答!关注公众号:算法与编程之美,我们会不断的更新力扣周赛题解,codeforces题解等比赛题解。
实习编辑:李欣容
稿件来源:深度学习与文旅应用实验室(DLETA)
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
​LeetCode刷题实战186:翻转字符串里的单词 II
【算法千题案例】每日LeetCode打卡——68.反转字符串中的元音字母
动态规划DP问题分类和经典题型
刻意练习:LeetCode实战 -- 不同的二叉搜索树
力扣132. 分割回文串 II-C语言实现-困难题
LeetCode 647. 回文子串(DP/中心扩展)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服