diff --git a/solution/2100-2199/2189.Number of Ways to Build House of Cards/README.md b/solution/2100-2199/2189.Number of Ways to Build House of Cards/README.md index f7b856ad72188..3b64fd7f9dc19 100644 --- a/solution/2100-2199/2189.Number of Ways to Build House of Cards/README.md +++ b/solution/2100-2199/2189.Number of Ways to Build House of Cards/README.md @@ -75,13 +75,13 @@ tags: 我们注意到,每一层的卡片数量为 $3 \times k + 2$,并且每一层的卡片数量都不相同。因此,问题可以转化为:整数 $n$ 可以由多少种 $3 \times k + 2$ 的数相加得到。这是一个经典的背包问题,可以使用记忆化搜索解决。 -我们设计一个函数 $dfs(n, k)$,表示当前剩余卡片数量为 $n$,且当前层为 $k$ 时,可以构建多少不同的纸牌屋。那么答案就是 $dfs(n, 0)$。 +我们设计一个函数 $\text{dfs}(n, k)$,表示当前剩余卡片数量为 $n$,且当前层为 $k$ 时,可以构建多少不同的纸牌屋。那么答案就是 $\text{dfs}(n, 0)$。 -函数 $dfs(n, k)$ 的执行逻辑如下: +函数 $\text{dfs}(n, k)$ 的执行逻辑如下: - 如果 $3 \times k + 2 \gt n$,那么当前层无法放置任何卡片,返回 $0$; - 如果 $3 \times k + 2 = n$,那么当前层可以放置卡片,放置完毕后,整个纸牌屋已经构建完毕,返回 $1$; -- 否则,我们可以选择不放置卡片,或者放置卡片。如果选择不放置卡片,那么剩余卡片数量不变,层数增加 $1$,即 $dfs(n, k + 1)$;如果选择放置卡片,那么剩余卡片数量减少 $3 \times k + 2$,层数增加 $1$,即 $dfs(n - (3 \times k + 2), k + 1)$。两者相加即为答案。 +- 否则,我们可以选择不放置卡片,或者放置卡片。如果选择不放置卡片,那么剩余卡片数量不变,层数增加 $1$,即 $\text{dfs}(n, k + 1)$;如果选择放置卡片,那么剩余卡片数量减少 $3 \times k + 2$,层数增加 $1$,即 $\text{dfs}(n - (3 \times k + 2), k + 1)$。两者相加即为答案。 过程中,我们可以使用记忆化搜索,避免重复计算。 @@ -141,7 +141,7 @@ public: int houseOfCards(int n) { int f[n + 1][n / 3 + 1]; memset(f, -1, sizeof(f)); - function dfs = [&](int n, int k) -> int { + auto dfs = [&](this auto&& dfs, int n, int k) -> int { int x = 3 * k + 2; if (x > n) { return 0; diff --git a/solution/2100-2199/2189.Number of Ways to Build House of Cards/README_EN.md b/solution/2100-2199/2189.Number of Ways to Build House of Cards/README_EN.md index 539f86fc31198..9efaf0be3bdce 100644 --- a/solution/2100-2199/2189.Number of Ways to Build House of Cards/README_EN.md +++ b/solution/2100-2199/2189.Number of Ways to Build House of Cards/README_EN.md @@ -71,7 +71,21 @@ The third house of cards uses 2 cards. -### Solution 1 +### Solution 1: Memoization Search + +We notice that the number of cards in each layer is $3 \times k + 2$, and the number of cards in each layer is different. Therefore, the problem can be transformed into: how many ways can the integer $n$ be expressed as the sum of numbers of the form $3 \times k + 2$. This is a classic knapsack problem that can be solved using memoization search. + +We design a function $\text{dfs}(n, k)$, which represents the number of ways to build different houses of cards when the remaining number of cards is $n$ and the current layer is $k$. The answer is $\text{dfs}(n, 0)$. + +The execution logic of the function $\text{dfs}(n, k)$ is as follows: + +- If $3 \times k + 2 \gt n$, then the current layer cannot place any cards, return $0$; +- If $3 \times k + 2 = n$, then the current layer can place cards, and after placing them, the entire house of cards is completed, return $1$; +- Otherwise, we can choose not to place cards or to place cards. If we choose not to place cards, the remaining number of cards does not change, and the number of layers increases by $1$, i.e., $\text{dfs}(n, k + 1)$. If we choose to place cards, the remaining number of cards decreases by $3 \times k + 2$, and the number of layers increases by $1$, i.e., $\text{dfs}(n - (3 \times k + 2), k + 1)$. The sum of these two cases is the answer. + +During the process, we can use memoization to avoid repeated calculations. + +The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Here, $n$ is the number of cards. @@ -127,7 +141,7 @@ public: int houseOfCards(int n) { int f[n + 1][n / 3 + 1]; memset(f, -1, sizeof(f)); - function dfs = [&](int n, int k) -> int { + auto dfs = [&](this auto&& dfs, int n, int k) -> int { int x = 3 * k + 2; if (x > n) { return 0; diff --git a/solution/2100-2199/2189.Number of Ways to Build House of Cards/Solution.cpp b/solution/2100-2199/2189.Number of Ways to Build House of Cards/Solution.cpp index f5192fc6777c2..166ccb193a306 100644 --- a/solution/2100-2199/2189.Number of Ways to Build House of Cards/Solution.cpp +++ b/solution/2100-2199/2189.Number of Ways to Build House of Cards/Solution.cpp @@ -3,7 +3,7 @@ class Solution { int houseOfCards(int n) { int f[n + 1][n / 3 + 1]; memset(f, -1, sizeof(f)); - function dfs = [&](int n, int k) -> int { + auto dfs = [&](this auto&& dfs, int n, int k) -> int { int x = 3 * k + 2; if (x > n) { return 0; @@ -18,4 +18,4 @@ class Solution { }; return dfs(n, 0); } -}; \ No newline at end of file +}; diff --git a/solution/2200-2299/2214.Minimum Health to Beat Game/README.md b/solution/2200-2299/2214.Minimum Health to Beat Game/README.md index 03ad47dfe2fe9..ac4f8004146db 100644 --- a/solution/2200-2299/2214.Minimum Health to Beat Game/README.md +++ b/solution/2200-2299/2214.Minimum Health to Beat Game/README.md @@ -83,9 +83,9 @@ tags: ### 方法一:贪心 -我们可以贪心地选择在伤害值最大的回合中使用一次护甲技能,假设伤害值最大为 $mx$,那么我们可以免受 $min(mx, armor)$ 的伤害,因此我们需要的最小生命值为 $sum(damage) - min(mx, armor) + 1$。 +我们可以贪心地选择在伤害值最大的回合中使用一次护甲技能,假设伤害值最大为 $\textit{mx}$,那么我们可以免受 $\min(\textit{mx}, \textit{armor})$ 的伤害,因此我们需要的最小生命值为 $\sum(\textit{damage}) - \min(\textit{mx}, \textit{armor}) + 1$。 -时间复杂度 $O(n)$,其中 $n$ 为数组 `damage` 的长度。空间复杂度 $O(1)$。 +时间复杂度 $O(n)$,其中 $n$ 为数组 $\textit{damage}$ 的长度。空间复杂度 $O(1)$。 diff --git a/solution/2200-2299/2214.Minimum Health to Beat Game/README_EN.md b/solution/2200-2299/2214.Minimum Health to Beat Game/README_EN.md index 452854014cf69..39b837183a4e8 100644 --- a/solution/2200-2299/2214.Minimum Health to Beat Game/README_EN.md +++ b/solution/2200-2299/2214.Minimum Health to Beat Game/README_EN.md @@ -82,9 +82,9 @@ Note that you did not use your armor ability. ### Solution 1: Greedy -We can greedily choose to use the armor skill in the round with the maximum damage. Suppose the maximum damage is $mx$, then we can avoid $min(mx, armor)$ damage, so the minimum life value we need is $sum(damage) - min(mx, armor) + 1$. +We can greedily choose to use the armor skill in the round with the highest damage. Suppose the maximum damage is $\textit{mx}$, then we can avoid $\min(\textit{mx}, \textit{armor})$ damage. Therefore, the minimum health required is $\sum(\textit{damage}) - \min(\textit{mx}, \textit{armor}) + 1$. -The time complexity is $O(n)$, where $n$ is the length of the `damage` array. The space complexity is $O(1)$. +The time complexity is $O(n)$, where $n$ is the length of the array $\textit{damage}$. The space complexity is $O(1)$. diff --git a/solution/2200-2299/2243.Calculate Digit Sum of a String/README.md b/solution/2200-2299/2243.Calculate Digit Sum of a String/README.md index 0a686aa5b5dd6..acca2648edfc0 100644 --- a/solution/2200-2299/2243.Calculate Digit Sum of a String/README.md +++ b/solution/2200-2299/2243.Calculate Digit Sum of a String/README.md @@ -39,11 +39,11 @@ tags: 输出:"135" 解释: - 第一轮,将 s 分成:"111"、"112"、"222" 和 "23" 。 - 接着,计算每一组的数字和:1 + 1 + 1 = 3、1 + 1 + 2 = 4、2 + 2 + 2 = 6 和 2 + 3 = 5 。 + 接着,计算每一组的数字和:1 + 1 + 1 = 3、1 + 1 + 2 = 4、2 + 2 + 2 = 6 和 2 + 3 = 5 。   这样,s 在第一轮之后变成 "3" + "4" + "6" + "5" = "3465" 。 - 第二轮,将 s 分成:"346" 和 "5" 。   接着,计算每一组的数字和:3 + 4 + 6 = 13 、5 = 5 。 -  这样,s 在第二轮之后变成 "13" + "5" = "135" 。 +  这样,s 在第二轮之后变成 "13" + "5" = "135" 。 现在,s.length <= k ,所以返回 "135" 作为答案。 @@ -53,7 +53,7 @@ tags: 输出:"000" 解释: 将 "000", "000", and "00". -接着,计算每一组的数字和:0 + 0 + 0 = 0 、0 + 0 + 0 = 0 和 0 + 0 = 0 。 +接着,计算每一组的数字和:0 + 0 + 0 = 0 、0 + 0 + 0 = 0 和 0 + 0 = 0 。 s 变为 "0" + "0" + "0" = "000" ,其长度等于 k ,所以返回 "000" 。 @@ -184,28 +184,4 @@ function digitSum(s: string, k: number): string { - - -### 方法二 - - - -#### Python3 - -```python -class Solution: - def digitSum(self, s: str, k: int) -> str: - if len(s) <= k: - return s - t = [] - while s: - t.append(str(sum(int(v) for v in s[:k]))) - s = s[k:] - return self.digitSum(''.join(t), k) -``` - - - - - diff --git a/solution/2200-2299/2243.Calculate Digit Sum of a String/README_EN.md b/solution/2200-2299/2243.Calculate Digit Sum of a String/README_EN.md index 24f5b5e1dc55e..067f1f646888e 100644 --- a/solution/2200-2299/2243.Calculate Digit Sum of a String/README_EN.md +++ b/solution/2200-2299/2243.Calculate Digit Sum of a String/README_EN.md @@ -37,13 +37,13 @@ tags:
 Input: s = "11111222223", k = 3
 Output: "135"
-Explanation: 
+Explanation:
 - For the first round, we divide s into groups of size 3: "111", "112", "222", and "23".
-  ​​​​​Then we calculate the digit sum of each group: 1 + 1 + 1 = 3, 1 + 1 + 2 = 4, 2 + 2 + 2 = 6, and 2 + 3 = 5. 
+  ​​​​​Then we calculate the digit sum of each group: 1 + 1 + 1 = 3, 1 + 1 + 2 = 4, 2 + 2 + 2 = 6, and 2 + 3 = 5.
   So, s becomes "3" + "4" + "6" + "5" = "3465" after the first round.
 - For the second round, we divide s into "346" and "5".
-  Then we calculate the digit sum of each group: 3 + 4 + 6 = 13, 5 = 5. 
-  So, s becomes "13" + "5" = "135" after second round. 
+  Then we calculate the digit sum of each group: 3 + 4 + 6 = 13, 5 = 5.
+  So, s becomes "13" + "5" = "135" after second round.
 Now, s.length <= k, so we return "135" as the answer.
 
@@ -52,9 +52,9 @@ Now, s.length <= k, so we return "135" as the answer.
 Input: s = "00000000", k = 3
 Output: "000"
-Explanation: 
+Explanation:
 We divide s into "000", "000", and "00".
-Then we calculate the digit sum of each group: 0 + 0 + 0 = 0, 0 + 0 + 0 = 0, and 0 + 0 = 0. 
+Then we calculate the digit sum of each group: 0 + 0 + 0 = 0, 0 + 0 + 0 = 0, and 0 + 0 = 0.
 s becomes "0" + "0" + "0" = "000", whose length is equal to k, so we return "000".
 
@@ -180,28 +180,4 @@ function digitSum(s: string, k: number): string { - - -### Solution 2 - - - -#### Python3 - -```python -class Solution: - def digitSum(self, s: str, k: int) -> str: - if len(s) <= k: - return s - t = [] - while s: - t.append(str(sum(int(v) for v in s[:k]))) - s = s[k:] - return self.digitSum(''.join(t), k) -``` - - - - - diff --git a/solution/2200-2299/2243.Calculate Digit Sum of a String/Solution2.py b/solution/2200-2299/2243.Calculate Digit Sum of a String/Solution2.py deleted file mode 100644 index 99b32441c75b8..0000000000000 --- a/solution/2200-2299/2243.Calculate Digit Sum of a String/Solution2.py +++ /dev/null @@ -1,9 +0,0 @@ -class Solution: - def digitSum(self, s: str, k: int) -> str: - if len(s) <= k: - return s - t = [] - while s: - t.append(str(sum(int(v) for v in s[:k]))) - s = s[k:] - return self.digitSum(''.join(t), k) diff --git a/solution/2900-2999/2920.Maximum Points After Collecting Coins From All Nodes/README.md b/solution/2900-2999/2920.Maximum Points After Collecting Coins From All Nodes/README.md index 24490f679c037..8a088fc38e61f 100644 --- a/solution/2900-2999/2920.Maximum Points After Collecting Coins From All Nodes/README.md +++ b/solution/2900-2999/2920.Maximum Points After Collecting Coins From All Nodes/README.md @@ -41,13 +41,13 @@ tags:
 输入:edges = [[0,1],[1,2],[2,3]], coins = [10,10,3,3], k = 5
-输出:11                        
+输出:11
 解释:
 使用第一种方法收集节点 0 上的所有金币。总积分 = 10 - 5 = 5 。
 使用第一种方法收集节点 1 上的所有金币。总积分 = 5 + (10 - 5) = 10 。
 使用第二种方法收集节点 2 上的所有金币。所以节点 3 上的金币将会变为 floor(3 / 2) = 1 ,总积分 = 10 + floor(3 / 2) = 11 。
 使用第二种方法收集节点 3 上的所有金币。总积分 =  11 + floor(1 / 2) = 11.
-可以证明收集所有节点上的金币能获得的最大积分是 11 。 
+可以证明收集所有节点上的金币能获得的最大积分是 11 。
 

示例 2:

@@ -93,8 +93,7 @@ tags: 最后,我们返回当前节点使用两种方法中能获得的最大积分。 -为了避免重复计算,我们使用记忆化搜索的方法,将 $dfs(i, fa, j)$ 的结果存储到 $f[i][j]$ 中,其中 $f[i][j]$ 表示当前节点为 $i$,父节点为 $fa$,当前节点的金币数需要右移 $j$ 位,所能获得的最大积分。 - +为了避免重复计算,我们使用记忆化搜索的方法,将 $dfs(i, fa, j)$ 的结果存储到 $f[i][j]$ 中,其中 $f[i][j]$ 表示当前节点为 $i$,父节点为 $fa$,当前节点的金币数需要右移 $j$ 位,所能获得的最大 时间复杂度 $O(n \times \log M)$,空间复杂度 $O(n \times \log M)$。其中 $M$ 表示 $coins[i]$ 的最大值。 @@ -183,7 +182,7 @@ public: g[a].emplace_back(b); g[b].emplace_back(a); } - function dfs = [&](int i, int fa, int j) { + auto dfs = [&](this auto&& dfs, int i, int fa, int j) -> int { if (f[i][j] != -1) { return f[i][j]; } diff --git a/solution/2900-2999/2920.Maximum Points After Collecting Coins From All Nodes/README_EN.md b/solution/2900-2999/2920.Maximum Points After Collecting Coins From All Nodes/README_EN.md index c717dc6955ba8..74fc4d69e3d84 100644 --- a/solution/2900-2999/2920.Maximum Points After Collecting Coins From All Nodes/README_EN.md +++ b/solution/2900-2999/2920.Maximum Points After Collecting Coins From All Nodes/README_EN.md @@ -40,13 +40,13 @@ tags:
 Input: edges = [[0,1],[1,2],[2,3]], coins = [10,10,3,3], k = 5
-Output: 11                        
-Explanation: 
+Output: 11
+Explanation:
 Collect all the coins from node 0 using the first way. Total points = 10 - 5 = 5.
 Collect all the coins from node 1 using the first way. Total points = 5 + (10 - 5) = 10.
 Collect all the coins from node 2 using the second way so coins left at node 3 will be floor(3 / 2) = 1. Total points = 10 + floor(3 / 2) = 11.
 Collect all the coins from node 3 using the second way. Total points = 11 + floor(1 / 2) = 11.
-It can be shown that the maximum points we can get after collecting coins from all the nodes is 11. 
+It can be shown that the maximum points we can get after collecting coins from all the nodes is 11.
 

Example 2:

@@ -55,7 +55,7 @@ It can be shown that the maximum points we can get after collecting coins from a
 Input: edges = [[0,1],[0,2]], coins = [8,4,4], k = 0
 Output: 16
-Explanation: 
+Explanation:
 Coins will be collected from all the nodes using the first way. Therefore, total points = (8 - 0) + (4 - 0) + (4 - 0) = 16.
 
@@ -181,7 +181,7 @@ public: g[a].emplace_back(b); g[b].emplace_back(a); } - function dfs = [&](int i, int fa, int j) { + auto dfs = [&](this auto&& dfs, int i, int fa, int j) -> int { if (f[i][j] != -1) { return f[i][j]; } diff --git a/solution/2900-2999/2920.Maximum Points After Collecting Coins From All Nodes/Solution.cpp b/solution/2900-2999/2920.Maximum Points After Collecting Coins From All Nodes/Solution.cpp index e5d1388d305f2..05d821552f5ca 100644 --- a/solution/2900-2999/2920.Maximum Points After Collecting Coins From All Nodes/Solution.cpp +++ b/solution/2900-2999/2920.Maximum Points After Collecting Coins From All Nodes/Solution.cpp @@ -10,7 +10,7 @@ class Solution { g[a].emplace_back(b); g[b].emplace_back(a); } - function dfs = [&](int i, int fa, int j) { + auto dfs = [&](this auto&& dfs, int i, int fa, int j) -> int { if (f[i][j] != -1) { return f[i][j]; } @@ -28,4 +28,4 @@ class Solution { }; return dfs(0, -1, 0); } -}; \ No newline at end of file +};