ToB企服应用市场:ToB评测及商务社交产业平台

标题: Leetcode 第 142 场双周赛题解 [打印本页]

作者: 魏晓东    时间: 2024-10-30 03:14
标题: Leetcode 第 142 场双周赛题解
Leetcode 第 142 场双周赛题解

题目1:3330. 找到初始输入字符串 I

思路

方案数等于相邻类似字母对的个数加 1。
代码

  1. /*
  2. * @lc app=leetcode.cn id=3330 lang=cpp
  3. *
  4. * [3330] 找到初始输入字符串 I
  5. */
  6. // @lc code=start
  7. class Solution
  8. {
  9. public:
  10.     int possibleStringCount(string word)
  11.     {
  12.         int ans = 1;
  13.         for (int i = 1; i < word.length(); i++)
  14.             if (word[i - 1] == word[i])
  15.                 ans++;
  16.         return ans;
  17.     }
  18. };
  19. // @lc code=end
复制代码
复杂度分析

时间复杂度:O(n),此中 n 是字符串 word 的长度。
空间复杂度:O(1)。
题目2:

思路

直接模仿,两次遍历。
一遍创建新树。创建新树不能直接在原来的树上直接修改,直接修改会导致已经遍历过的节点的子树受到影响。
一遍统计子树大小。
代码

  1. /*
  2. * @lc app=leetcode.cn id=3331 lang=cpp
  3. *
  4. * [3331] 修改后子树的大小
  5. */
  6. // @lc code=start
  7. class Solution
  8. {
  9. public:
  10.     vector<int> findSubtreeSizes(vector<int> &parent, string s)
  11.     {
  12.         int n = parent.size();
  13.         vector<int> newParent(n, 1);
  14.         // 建立新树
  15.         for (int i = 0; i < n; i++)
  16.         {
  17.             int t = parent[i];
  18.             while (t != -1 && s[t] != s[i])
  19.                 t = parent[t];
  20.             if (t != -1 && s[i] == s[t])
  21.                 newParent[i] = t;
  22.             else
  23.                 newParent[i] = parent[i];
  24.         }
  25.         // 统计子树大小
  26.         vector<int> ans(n, 1);
  27.         for (int i = 0; i < n; i++)
  28.         {
  29.             int t = newParent[i];
  30.             while (t != -1)
  31.             {
  32.                 ans[t]++;
  33.                 t = newParent[t];
  34.             }
  35.         }
  36.         return ans;
  37.     }
  38. };
  39. // @lc code=end
复制代码
复杂度分析

时间复杂度:O(n+∣Σ∣),此中 n 是字符串 s 的长度,∣Σ∣=26 是字符聚集的大小。
空间复杂度:O(n),此中 n 是字符串 s 的长度。
题目3:3332. 旅客可以得到的最多点数

思路

定义状态为 dfs(i,j),表示第 i 天到第 k−1 天,从都会 j 开始旅游,可以得到的最多点数。
分类讨论:

所有情况取最大值,就得到了 dfs(i,j)。
代码

动态规划:
  1. /*
  2. * @lc app=leetcode.cn id=3332 lang=cpp
  3. *
  4. * [3332] 旅客可以得到的最多点数
  5. */
  6. // @lc code=start
  7. class Solution
  8. {
  9. public:
  10.     int maxScore(int n, int k, vector<vector<int>> &stayScore, vector<vector<int>> &travelScore)
  11.     {
  12.         vector<vector<int>> dp(k + 1, vector<int>(n, 0));
  13.         // 状态转移
  14.         for (int i = 1; i <= k; i++)
  15.             for (int j = 0; j < n; j++)
  16.             {
  17.                 // 留在当前城市 j
  18.                 dp[i][j] = dp[i - 1][j] + stayScore[i - 1][j];
  19.                 // 来自另外一座城市 d
  20.                 for (int d = 0; d < n; d++)
  21.                     dp[i][j] = max(dp[i][j], dp[i - 1][d] + travelScore[d][j]);
  22.             }
  23.         int ans = INT_MIN;
  24.         // 枚举城市 i 作为终点
  25.         for (int i = 0; i < n; i++)
  26.             ans = max(ans, dp[k][i]);
  27.         return ans;
  28.     }
  29. };
  30. // @lc code=end
复制代码
影象化搜索:
  1. #
  2. # @lc app=leetcode.cn id=3332 lang=python3
  3. #
  4. # [3332] 旅客可以得到的最多点数
  5. #
  6. # @lc code=start
  7. class Solution:
  8.     def maxScore(self, n: int, k: int, stayScore: List[List[int]], travelScore: List[List[int]]) -> int:
  9.         
  10.         @cache
  11.         def dfs(i: int, j: int) -> int:
  12.             if i == k:
  13.                 return 0
  14.             # 留在当前城市 j
  15.             res1 = dfs(i + 1, j) + stayScore[i][j]
  16.             # 来自另外一座城市 d
  17.             res2 = max(dfs(i + 1, d) + s for d, s in enumerate(travelScore[j]))
  18.             
  19.             return max(res1, res2)
  20.         
  21.         return max(dfs(0, i) for i in range(n))  # 枚举城市 i 作为终点
  22. # @lc code=end
复制代码
复杂度分析

时间复杂度:O(kn2)。由于每个状态只管帐算一次,动态规划的时间复杂度 = 状态个数 × 单个状态的计算时间。本题状态个数等于 O(kn),单个状态的计算时间为 O(n),所以总的时间复杂度为 O(kn2)。
空间复杂度:O(kn)。保存多少状态,就需要多少空间。
题目4:

思路

正难则反+前缀和优化 DP
题解:
https://leetcode.cn/problems/find-the-original-typed-string-ii/solutions/2966856/zheng-nan-ze-fan-qian-zhui-he-you-hua-dp-5mi9/?source=vscode
代码

  1. /*
  2. * @lc app=leetcode.cn id=3333 lang=cpp
  3. *
  4. * [3333] 找到初始输入字符串 II
  5. */
  6. // @lc code=start
  7. class Solution
  8. {
  9. private:
  10.     const int MOD = 1'000'000'007;
  11. public:
  12.     int possibleStringCount(string word, int k)
  13.     {
  14.         int n = word.length();
  15.         if (n < k)
  16.             return 0;
  17.         vector<int> cnts;
  18.         long long ans = 1;
  19.         int cnt = 0;
  20.         for (int i = 0; i < n; i++)
  21.         {
  22.             cnt++;
  23.             if (i == n - 1 || word[i] != word[i + 1])
  24.             {
  25.                 if (cnts.size() < k)
  26.                     cnts.push_back(cnt);
  27.                 ans = ans * cnt % MOD;
  28.                 cnt = 0;
  29.             }
  30.         }
  31.         int m = cnts.size();
  32.         if (m >= k) // 任何输入的字符串都至少为 k
  33.             return ans;
  34.         vector<vector<int>> dp(m + 1, vector<int>(k));
  35.         // 初始化
  36.         dp[0][0] = 1;
  37.         vector<int> s(k + 1);
  38.         // 状态转移
  39.         for (int i = 0; i < m; i++)
  40.         {
  41.             for (int j = 0; j < k; j++)
  42.                 s[j + 1] = (s[j] + dp[i][j]) % MOD;
  43.             // j <= i 的 dp[i][j] 都是 0
  44.             for (int j = i + 1; j < k; j++)
  45.                 dp[i + 1][j] = (s[j] - s[max(j - cnts[i], 0)]) % MOD;
  46.         }
  47.         ans -= reduce(dp[m].begin() + m, dp[m].end(), 0LL);
  48.         return (ans % MOD + MOD) % MOD; // 保证结果非负
  49.     }
  50. };
  51. // @lc code=end
复制代码
复杂度分析

时间复杂度:O(n+k2),此中 n 是字符串 word 的长度。
空间复杂度:O(k)。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4