力扣266场周赛

Posted 算法与编程之美

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣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)

以上是关于力扣266场周赛的主要内容,如果未能解决你的问题,请参考以下文章

解题报告力扣 第 285 场周赛

解题报告力扣 第 277 场周赛

解题报告力扣 第 263 场周赛

解题报告力扣 第 269 场周赛

解题报告力扣 第 288 场周赛

解题报告力扣 第 279 场周赛