LeetCode 213周赛题解

淡淡的烟草味﹌ 2022-11-21 15:08 302阅读 0赞

A-1640. 能否连接形成数组

题意:

给你一个整数数组 arr ,数组中的每个整数 互不相同 。另有一个由整数数组构成的数组 pieces,其中的整数也 互不相同 。请你以 任意顺序 连接 pieces 中的数组以形成 arr 。但是,不允许 对每个数组 pieces[i] 中的整数重新排序。

如果可以连接 pieces 中的数组形成 arr ,返回 true ;否则,返回 false 。

思路:

由于每个数字都不相同,所以我们只要看每个子数组在arr中是否连续出现即可。

Code:

  1. class Solution {
  2. public:
  3. bool canFormArray(vector<int>& arr, vector<vector<int>>& pieces) {
  4. for(auto v :pieces)
  5. {
  6. int len = 0;
  7. for(int i = 0; i < arr.size(); ++i)
  8. {
  9. int cnt = 0;
  10. for(int j = 0; j < v.size() && i + j < arr.size(); ++j)
  11. {
  12. if(v[j] == arr[i + j])
  13. ++cnt;
  14. }
  15. len = max(len, cnt);
  16. }
  17. if(len != v.size())
  18. return false;
  19. }
  20. return true;
  21. }
  22. };

B-1641. 统计字典序元音字符串的数目

题意:

给你一个整数 n,请返回长度为 n 、仅由元音 (a, e, i, o, u) 组成且按 字典序排列 的字符串数量。

字符串 s 按 字典序排列 需要满足:对于所有有效的 i,s[i] 在字母表中的位置总是与 s[i+1] 相同或在 s[i+1] 之前。

思路:

用DP或者DFS其实都可以,我就说说我场上的写法,找到4的答案查了一波oeis发现就是n * (n - 1) * (n - 2) * (n - 3) / 24

Code:

  1. class Solution {
  2. public:
  3. int countVowelStrings(int n) {
  4. n = n + 4;
  5. return n*(n-1)*(n-2)*(n-3)/24;
  6. }
  7. };

C-1642. 可以到达的最远建筑

题意:

给你一个整数数组 heights ,表示建筑物的高度。另有一些砖块 bricks 和梯子 ladders 。

你从建筑物 0 开始旅程,不断向后面的建筑物移动,期间可能会用到砖块或梯子。

当从建筑物 i 移动到建筑物 i+1(下标 从 0 开始 )时:

如果当前建筑物的高度 大于或等于 下一建筑物的高度,则不需要梯子或砖块
如果当前建筑的高度 小于 下一个建筑的高度,您可以使用 一架梯子 或 (h[i+1] - h[i]) 个砖块
如果以最佳方式使用给定的梯子和砖块,返回你可以到达的最远建筑物的下标(下标 从 0 开始 )。

思路:

贪心来讲,需要砖头较多的用梯子比较划算,所以我们用堆来维护ladders个最大的砖头数,看最远能延伸多远。

Code:

  1. class Solution {
  2. public:
  3. priority_queue<int, vector<int>, greater<int> > q;
  4. long long sum = 0, now = 0;
  5. int furthestBuilding(vector<int>& heights, int bricks, int ladders)
  6. {
  7. while(!q.empty()) q.pop();
  8. int ans = 0;
  9. for(int i = 1; i < heights.size(); ++i)
  10. {
  11. int d = heights[i] - heights[i - 1];
  12. if(d > 0)
  13. q.push(d);
  14. if(q.size() > ladders)
  15. sum += q.top(), q.pop();
  16. if(sum <= bricks)
  17. ans = i;
  18. }
  19. return ans;
  20. }
  21. };

D-5600. 第 K 条最小指令

题意:

Bob 站在单元格 (0, 0) ,想要前往目的地 destination :(row, column) 。他只能向 右 或向 下 走。你可以为 Bob 提供导航 指令 来帮助他到达目的地 destination 。

指令 用字符串表示,其中每个字符:

‘H’ ,意味着水平向右移动
‘V’ ,意味着竖直向下移动
能够为 Bob 导航到目的地 destination 的指令可以有多种,例如,如果目的地 destination 是 (2, 3),“HHHVV” 和 “HVHVH” 都是有效 指令 。

然而,Bob 很挑剔。因为他的幸运数字是 k,他想要遵循 按字典序排列后的第 k 条最小指令 的导航前往目的地 destination 。k 的编号 从 1 开始 。

给你一个整数数组 destination 和一个整数 k ,请你返回可以为 Bob 提供前往目的地 destination 导航的 按字典序排列后的第 k 条最小指令 。

思路:

也就是给你n个‘V’和m个‘H’,让你找到字典序第k大的序列。

首先我们有C(n + m, m)种方案数,因为相当于在n+m中选择哪一次向下走。

那么我们就看第一次是用H还是用V,可以通过判断是否大于k来决定。然后就把剩下的子问题同样的步骤处理即可

Code:

  1. typedef long long ll;
  2. const int maxn = 30 + 10;
  3. class Solution {
  4. public:
  5. ll C[maxn][maxn];
  6. string kthSmallestPath(vector<int>& destination, int k)
  7. {
  8. C[0][0] = 1; //组合数打表
  9. for(int i = 1; i < maxn; ++i)
  10. {
  11. C[i][0] = C[i][i] = 1;
  12. for(int j = 1; j < i; ++j)
  13. C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
  14. }
  15. int n = destination[1], m = destination[0], lim = n + m;
  16. string res;
  17. for(int i = 1; i <= lim; ++i)
  18. {
  19. if(n >= 1 && C[n + m - 1][m] >= k) //看当前位是‘H’还是‘V’
  20. {
  21. res.push_back('H');
  22. --n; //用过一个‘H’
  23. }
  24. else
  25. {
  26. res.push_back('V');
  27. k -= C[n + m - 1][m];
  28. --m;
  29. }
  30. }
  31. return res;
  32. }
  33. };

发表评论

表情:
评论列表 (有 0 条评论,302人围观)

还没有评论,来说两句吧...

相关阅读

    相关 LeetCode 216题解

    这场比赛题目比较简单,真\手速场B题读错题意wa了一发,改了就过了。D题手滑运行点成提交了也wa了一发,,还好改了都过了。 [5605. 检查两个字符串数组是否相等][56