• 308场周赛 leetcode xp_xht123


    每周的周赛,虽然不能每一次ak,但是肯定还是需要总结的,从308场周赛开始总结

    第一题,2389,和有限的最长子序列

    题目描述:

    给你一个长度为 n 的整数数组 nums ,和一个长度为 m 的整数数组 queries 。

    返回一个长度为 m 的数组 answer ,其中 answer[i] 是 nums 中 元素之和小于等于 queries[i] 的 子序列 的 最大 长度  。

    子序列 是由一个数组删除某些元素(也可以不删除)但不改变剩余元素顺序得到的一个数组。

     

    示例 1:

    输入:nums = [4,5,2,1], queries = [3,10,21]
    输出:[2,3,4]
    解释:queries 对应的 answer 如下:
    - 子序列 [2,1] 的和小于或等于 3 。可以证明满足题目要求的子序列的最大长度是 2 ,所以 answer[0] = 2 。
    - 子序列 [4,5,1] 的和小于或等于 10 。可以证明满足题目要求的子序列的最大长度是 3 ,所以 answer[1] = 3 。
    - 子序列 [4,5,2,1] 的和小于或等于 21 。可以证明满足题目要求的子序列的最大长度是 4 ,所以 answer[2] = 4 。


    示例 2:

    输入:nums = [2,3,4,5], queries = [1]
    输出:[0]
    解释:空子序列是唯一一个满足元素和小于或等于 1 的子序列,所以 answer[0] = 0 。

    前缀和+排序

    首先先排序,然后计算前缀和,最后对于每一个询问,到序遍历一遍数组即可,即可找到答案,这样的复杂度为O(nlogn + nm),当然可以使用二分查找去找到合适的坐标,这样时间复杂度可以降到O((m + n)logn)

    1. class Solution {
    2. public:
    3. vector<int> answerQueries(vector<int>& nums, vector<int>& queries)
    4. {
    5. vector<int>res;
    6. sort(nums.begin() , nums.end());
    7. int s[1010];
    8. s[0] = nums[0];
    9. for(int i = 1;i < nums.size();i ++)
    10. s[i] = s[i - 1] + nums[i];
    11. for(int i = 0;i < queries.size();i ++)
    12. {
    13. int x = queries[i];
    14. if(x < s[0])
    15. {
    16. res.push_back(0);
    17. continue;
    18. }
    19. int j;
    20. for(j = nums.size() - 1;j >= 0;j --)
    21. {
    22. if(s[j] <= x) break;
    23. }
    24. res.push_back(j + 1);
    25. }
    26. return res;
    27. }
    28. };

    第二题:2309从字符串中移除星号

    题目描述:

    给你一个包含若干星号 * 的字符串 s 。

    在一步操作中,你可以:

    选中 s 中的一个星号。
    移除星号 左侧 最近的那个 非星号 字符,并移除该星号自身。
    返回移除 所有 星号之后的字符串。

    注意:

    生成的输入保证总是可以执行题面中描述的操作。
    可以证明结果字符串是唯一的。
     

    示例 1:

    输入:s = "leet**cod*e"
    输出:"lecoe"
    解释:从左到右执行移除操作:
    - 距离第 1 个星号最近的字符是 "leet**cod*e" 中的 't' ,s 变为 "lee*cod*e" 。
    - 距离第 2 个星号最近的字符是 "lee*cod*e" 中的 'e' ,s 变为 "lecod*e" 。
    - 距离第 3 个星号最近的字符是 "lecod*e" 中的 'd' ,s 变为 "lecoe" 。
    不存在其他星号,返回 "lecoe" 。


    示例 2:

    输入:s = "erase*****"
    输出:""
    解释:整个字符串都会被移除,所以返回空字符串。

    栈的应用

    首先先建立一个栈,每次遇见一个不是星号的字符推入栈,如果是星号,在保证栈非空的情况下弹出栈顶,最后栈中的元素逆序就是答案

    1. class Solution {
    2. public:
    3. string removeStars(string s)
    4. {
    5. stack<char>st;
    6. for(int i = 0;i < s.length();i ++)
    7. {
    8. if(s[i] != '*') st.push(s[i]);
    9. else
    10. {
    11. if(!st.empty()) st.pop();
    12. }
    13. }
    14. string res;
    15. while(!st.empty())
    16. {
    17. char ch = st.top();
    18. st.pop();
    19. res += ch;
    20. }
    21. if(res.size()) reverse(res.begin() , res.end());
    22. return res;
    23. }
    24. };

    第三题:

    题目描述

    给你一个下标从 0 开始的字符串数组 garbage ,其中 garbage[i] 表示第 i 个房子的垃圾集合。garbage[i] 只包含字符 'M' ,'P' 和 'G' ,但可能包含多个相同字符,每个字符分别表示一单位的金属、纸和玻璃。垃圾车收拾 一 单位的任何一种垃圾都需要花费 1 分钟。

    同时给你一个下标从 0 开始的整数数组 travel ,其中 travel[i] 是垃圾车从房子 i 行驶到房子 i + 1 需要的分钟数。

    城市里总共有三辆垃圾车,分别收拾三种垃圾。每辆垃圾车都从房子 0 出发,按顺序 到达每一栋房子。但它们 不是必须 到达所有的房子。

    任何时刻只有 一辆 垃圾车处在使用状态。当一辆垃圾车在行驶或者收拾垃圾的时候,另外两辆车 不能 做任何事情。

    请你返回收拾完所有垃圾需要花费的 最少 总分钟数。

    示例 1:

    输入:garbage = ["G","P","GP","GG"], travel = [2,4,3]
    输出:21
    解释:
    收拾纸的垃圾车:
    1. 从房子 0 行驶到房子 1
    2. 收拾房子 1 的纸垃圾
    3. 从房子 1 行驶到房子 2
    4. 收拾房子 2 的纸垃圾
    收拾纸的垃圾车总共花费 8 分钟收拾完所有的纸垃圾。
    收拾玻璃的垃圾车:
    1. 收拾房子 0 的玻璃垃圾
    2. 从房子 0 行驶到房子 1
    3. 从房子 1 行驶到房子 2
    4. 收拾房子 2 的玻璃垃圾
    5. 从房子 2 行驶到房子 3
    6. 收拾房子 3 的玻璃垃圾
    收拾玻璃的垃圾车总共花费 13 分钟收拾完所有的玻璃垃圾。
    由于没有金属垃圾,收拾金属的垃圾车不需要花费任何时间。
    所以总共花费 8 + 13 = 21 分钟收拾完所有垃圾。


    示例 2:

    输入:garbage = ["MMM","PGM","GP"], travel = [3,10]
    输出:37
    解释:
    收拾金属的垃圾车花费 7 分钟收拾完所有的金属垃圾。
    收拾纸的垃圾车花费 15 分钟收拾完所有的纸垃圾。
    收拾玻璃的垃圾车花费 15 分钟收拾完所有的玻璃垃圾。
    总共花费 7 + 15 + 15 = 37 分钟收拾完所有的垃圾。

    前缀和+模拟

    先计算,时间的前缀和,每一种情况,只用找到到达最远的位置所需要的时间+处理每一种情况所用的处理时间数就行,把所有的情况算出即可求出答案

    1. class Solution
    2. {
    3. public:
    4. int s[100010] = {0};
    5. unordered_map<int , vector<int> >mp;
    6. public:
    7. void get_time(int type , int &res , int n)
    8. {
    9. int idx = 0;
    10. for(int j = 0;j < n;j ++)
    11. {
    12. if(mp[j][type])
    13. {
    14. res += mp[j][type];
    15. idx = j;
    16. }
    17. }
    18. if(idx >= 1) res += s[idx - 1];
    19. }
    20. int garbageCollection(vector& garbage, vector<int>& travel)
    21. {
    22. s[0] = travel[0];
    23. for(int i = 1;i < travel.size();i ++)
    24. s[i] = s[i - 1] + travel[i];
    25. int n = garbage.size();
    26. for(int i = 0;i < n;i ++)
    27. {
    28. string x = garbage[i];
    29. int m = 0 , p = 0 , g = 0;
    30. for(int j = 0;j < x.size();j ++)
    31. {
    32. if(x[j] == 'M') m ++;
    33. else if(x[j] == 'P') p ++;
    34. else g ++;
    35. }
    36. mp[i].push_back(m) , mp[i].push_back(p) , mp[i].push_back(g);
    37. }
    38. int res = 0;
    39. for(int i = 0;i < 3;i ++)
    40. get_time(i , res , n);
    41. return res;
    42. }
    43. };

    第四题:

    题目描述:

    给你一个 正 整数 k ,同时给你:

    一个大小为 n 的二维整数数组 rowConditions ,其中 rowConditions[i] = [abovei, belowi] 和
    一个大小为 m 的二维整数数组 colConditions ,其中 colConditions[i] = [lefti, righti] 。
    两个数组里的整数都是 1 到 k 之间的数字。

    你需要构造一个 k x k 的矩阵,1 到 k 每个数字需要 恰好出现一次 。剩余的数字都是 0 。

    矩阵还需要满足以下条件:

    对于所有 0 到 n - 1 之间的下标 i ,数字 abovei 所在的 行 必须在数字 belowi 所在行的上面。
    对于所有 0 到 m - 1 之间的下标 i ,数字 lefti 所在的 列 必须在数字 righti 所在列的左边。
    返回满足上述要求的 任意 矩阵。如果不存在答案,返回一个空的矩阵。

    示例 1:

    输入:k = 3, rowConditions = [[1,2],[3,2]], colConditions = [[2,1],[3,2]]
    输出:[[3,0,0],[0,0,1],[0,2,0]]
    解释:
    行要求如下:
    - 数字 1 在第 1 行,数字 2 在第 2 行,1 在 2 的上面。
    - 数字 3 在第 0 行,数字 2 在第 2 行,3 在 2 的上面。
    列要求如下:
    - 数字 2 在第 1 列,数字 1 在第 2 列,2 在 1 的左边。
    - 数字 3 在第 0 列,数字 2 在第 1 列,3 在 2 的左边。
    注意,可能有多种正确的答案。


    示例 2:

    输入:k = 3, rowConditions = [[1,2],[2,3],[3,1],[2,3]], colConditions = [[2,1]]
    输出:[]
    解释:由前两个条件可以得到 3 在 1 的下面,但第三个条件是 3 在 1 的上面。
    没有符合条件的矩阵存在,所以我们返回空矩阵。

    拓扑排序

    当时一开始做的时候想到的是dfs,一直做不出来,结束了看了解析豁然开朗,原来是拓扑排序,分别对行和列进行拓扑排序,求出每个数字所在的排名。如果拓扑排序不存在,则说明答案不存在。按照行和列的排名填充最终的矩阵。

    1. class Solution {
    2. public:
    3. vector<int> tops(int k , vectorint>>& v)
    4. {
    5. vector<int>res(k);
    6. int d[410] = {0};
    7. vectorint>>g(k);
    8. //拓扑排序做事的顺序
    9. for(auto i : v)
    10. {
    11. int a = i[0] - 1 , b = i[1] - 1;
    12. g[a].push_back(b);
    13. d[b] ++;
    14. }
    15. queue<int>q;
    16. //找起点 入度为0的点
    17. for(int i = 0;i < k;i ++)
    18. if(!d[i]) q.push(i);
    19. int x = 0;
    20. while(!q.empty())
    21. {
    22. int t = q.front();
    23. q.pop();
    24. res[t] = x ++;
    25. for(int i : g[t])
    26. {
    27. d[i] --;
    28. if(!d[i]) q.push(i);
    29. }
    30. }
    31. for(int i = 0;i < k;i ++)
    32. if(d[i]) return {};
    33. return res;
    34. }
    35. vectorint>> buildMatrix(int k, vectorint>>& rowConditions, vectorint>>& colConditions)
    36. {
    37. vector<int>r = tops(k , rowConditions);
    38. if(r.empty()) return {};
    39. auto c = tops(k , colConditions);
    40. if(c.empty()) return {};
    41. vectorint> >res(k, vector<int>(k , 0));//定义一个k * k的矩阵每个位置都为0
    42. for(int i = 0;i < k;i ++)
    43. res[r[i]][c[i]] = i + 1;
    44. return res;
    45. }
    46. };

  • 相关阅读:
    【博客535】k8s证书原理:各类证书作用
    Win:在 Windows 中配置 Multiple VLANs 接口
    实时数仓中的分层
    软件研发的十大浪费:研发效能的另一面
    讲解LCD1602自定义字符原理
    EfficientNet:通过模型效率彻底改变深度学习
    Maven多环境下 active: @profileActive@报错问题解决
    AI智工作室11.19练习题解
    cat监控本地docker部署
    网络通信设备之交换网络技术详解一
  • 原文地址:https://blog.csdn.net/xp_xht123/article/details/126571978