Skip to content

Commit db26b5f

Browse files
authored
feat: update solutions to lc problems: No.2189,2920 (doocs#3985)
1 parent e780ccd commit db26b5f

File tree

11 files changed

+46
-90
lines changed

11 files changed

+46
-90
lines changed

solution/2100-2199/2189.Number of Ways to Build House of Cards/README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,13 @@ tags:
7575

7676
我们注意到,每一层的卡片数量为 $3 \times k + 2$,并且每一层的卡片数量都不相同。因此,问题可以转化为:整数 $n$ 可以由多少种 $3 \times k + 2$ 的数相加得到。这是一个经典的背包问题,可以使用记忆化搜索解决。
7777

78-
我们设计一个函数 $dfs(n, k)$,表示当前剩余卡片数量为 $n$,且当前层为 $k$ 时,可以构建多少不同的纸牌屋。那么答案就是 $dfs(n, 0)$。
78+
我们设计一个函数 $\text{dfs}(n, k)$,表示当前剩余卡片数量为 $n$,且当前层为 $k$ 时,可以构建多少不同的纸牌屋。那么答案就是 $\text{dfs}(n, 0)$。
7979

80-
函数 $dfs(n, k)$ 的执行逻辑如下:
80+
函数 $\text{dfs}(n, k)$ 的执行逻辑如下:
8181

8282
- 如果 $3 \times k + 2 \gt n$,那么当前层无法放置任何卡片,返回 $0$;
8383
- 如果 $3 \times k + 2 = n$,那么当前层可以放置卡片,放置完毕后,整个纸牌屋已经构建完毕,返回 $1$;
84-
- 否则,我们可以选择不放置卡片,或者放置卡片。如果选择不放置卡片,那么剩余卡片数量不变,层数增加 $1$,即 $dfs(n, k + 1)$;如果选择放置卡片,那么剩余卡片数量减少 $3 \times k + 2$,层数增加 $1$,即 $dfs(n - (3 \times k + 2), k + 1)$。两者相加即为答案。
84+
- 否则,我们可以选择不放置卡片,或者放置卡片。如果选择不放置卡片,那么剩余卡片数量不变,层数增加 $1$,即 $\text{dfs}(n, k + 1)$;如果选择放置卡片,那么剩余卡片数量减少 $3 \times k + 2$,层数增加 $1$,即 $\text{dfs}(n - (3 \times k + 2), k + 1)$。两者相加即为答案。
8585

8686
过程中,我们可以使用记忆化搜索,避免重复计算。
8787

@@ -141,7 +141,7 @@ public:
141141
int houseOfCards(int n) {
142142
int f[n + 1][n / 3 + 1];
143143
memset(f, -1, sizeof(f));
144-
function<int(int, int)> dfs = [&](int n, int k) -> int {
144+
auto dfs = [&](this auto&& dfs, int n, int k) -> int {
145145
int x = 3 * k + 2;
146146
if (x > n) {
147147
return 0;

solution/2100-2199/2189.Number of Ways to Build House of Cards/README_EN.md

+16-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,21 @@ The third house of cards uses 2 cards.
7171

7272
<!-- solution:start -->
7373

74-
### Solution 1
74+
### Solution 1: Memoization Search
75+
76+
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.
77+
78+
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)$.
79+
80+
The execution logic of the function $\text{dfs}(n, k)$ is as follows:
81+
82+
- If $3 \times k + 2 \gt n$, then the current layer cannot place any cards, return $0$;
83+
- 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$;
84+
- 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.
85+
86+
During the process, we can use memoization to avoid repeated calculations.
87+
88+
The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Here, $n$ is the number of cards.
7589

7690
<!-- tabs:start -->
7791

@@ -127,7 +141,7 @@ public:
127141
int houseOfCards(int n) {
128142
int f[n + 1][n / 3 + 1];
129143
memset(f, -1, sizeof(f));
130-
function<int(int, int)> dfs = [&](int n, int k) -> int {
144+
auto dfs = [&](this auto&& dfs, int n, int k) -> int {
131145
int x = 3 * k + 2;
132146
if (x > n) {
133147
return 0;

solution/2100-2199/2189.Number of Ways to Build House of Cards/Solution.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ class Solution {
33
int houseOfCards(int n) {
44
int f[n + 1][n / 3 + 1];
55
memset(f, -1, sizeof(f));
6-
function<int(int, int)> dfs = [&](int n, int k) -> int {
6+
auto dfs = [&](this auto&& dfs, int n, int k) -> int {
77
int x = 3 * k + 2;
88
if (x > n) {
99
return 0;
@@ -18,4 +18,4 @@ class Solution {
1818
};
1919
return dfs(n, 0);
2020
}
21-
};
21+
};

solution/2200-2299/2214.Minimum Health to Beat Game/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ tags:
8383

8484
### 方法一:贪心
8585

86-
我们可以贪心地选择在伤害值最大的回合中使用一次护甲技能,假设伤害值最大为 $mx$,那么我们可以免受 $min(mx, armor)$ 的伤害,因此我们需要的最小生命值为 $sum(damage) - min(mx, armor) + 1$。
86+
我们可以贪心地选择在伤害值最大的回合中使用一次护甲技能,假设伤害值最大为 $\textit{mx}$,那么我们可以免受 $\min(\textit{mx}, \textit{armor})$ 的伤害,因此我们需要的最小生命值为 $\sum(\textit{damage}) - \min(\textit{mx}, \textit{armor}) + 1$。
8787

88-
时间复杂度 $O(n)$,其中 $n$ 为数组 `damage` 的长度。空间复杂度 $O(1)$。
88+
时间复杂度 $O(n)$,其中 $n$ 为数组 $\textit{damage}$ 的长度。空间复杂度 $O(1)$。
8989

9090
<!-- tabs:start -->
9191

solution/2200-2299/2214.Minimum Health to Beat Game/README_EN.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ Note that you did not use your armor ability.
8282

8383
### Solution 1: Greedy
8484

85-
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$.
85+
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$.
8686

87-
The time complexity is $O(n)$, where $n$ is the length of the `damage` array. The space complexity is $O(1)$.
87+
The time complexity is $O(n)$, where $n$ is the length of the array $\textit{damage}$. The space complexity is $O(1)$.
8888

8989
<!-- tabs:start -->
9090

solution/2200-2299/2243.Calculate Digit Sum of a String/README.md

+3-27
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ tags:
3939
<strong>输出:</strong>"135"
4040
<strong>解释:</strong>
4141
- 第一轮,将 s 分成:"111"、"112"、"222" 和 "23" 。
42-
接着,计算每一组的数字和:1 + 1 + 1 = 3、1 + 1 + 2 = 4、2 + 2 + 2 = 6 和 2 + 3 = 5 。
42+
接着,计算每一组的数字和:1 + 1 + 1 = 3、1 + 1 + 2 = 4、2 + 2 + 2 = 6 和 2 + 3 = 5 。
4343
&nbsp; 这样,s 在第一轮之后变成 "3" + "4" + "6" + "5" = "3465" 。
4444
- 第二轮,将 s 分成:"346" 和 "5" 。
4545
&nbsp; 接着,计算每一组的数字和:3 + 4 + 6 = 13 、5 = 5 。
46-
&nbsp; 这样,s 在第二轮之后变成 "13" + "5" = "135" 。
46+
&nbsp; 这样,s 在第二轮之后变成 "13" + "5" = "135" 。
4747
现在,s.length &lt;= k ,所以返回 "135" 作为答案。
4848
</pre>
4949

@@ -53,7 +53,7 @@ tags:
5353
<strong>输出:</strong>"000"
5454
<strong>解释:</strong>
5555
将 "000", "000", and "00".
56-
接着,计算每一组的数字和:0 + 0 + 0 = 0 、0 + 0 + 0 = 0 和 0 + 0 = 0 。
56+
接着,计算每一组的数字和:0 + 0 + 0 = 0 、0 + 0 + 0 = 0 和 0 + 0 = 0 。
5757
s 变为 "0" + "0" + "0" = "000" ,其长度等于 k ,所以返回 "000" 。
5858
</pre>
5959

@@ -184,28 +184,4 @@ function digitSum(s: string, k: number): string {
184184

185185
<!-- solution:end -->
186186

187-
<!-- solution:start -->
188-
189-
### 方法二
190-
191-
<!-- tabs:start -->
192-
193-
#### Python3
194-
195-
```python
196-
class Solution:
197-
def digitSum(self, s: str, k: int) -> str:
198-
if len(s) <= k:
199-
return s
200-
t = []
201-
while s:
202-
t.append(str(sum(int(v) for v in s[:k])))
203-
s = s[k:]
204-
return self.digitSum(''.join(t), k)
205-
```
206-
207-
<!-- tabs:end -->
208-
209-
<!-- solution:end -->
210-
211187
<!-- problem:end -->

solution/2200-2299/2243.Calculate Digit Sum of a String/README_EN.md

+6-30
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ tags:
3737
<pre>
3838
<strong>Input:</strong> s = &quot;11111222223&quot;, k = 3
3939
<strong>Output:</strong> &quot;135&quot;
40-
<strong>Explanation:</strong>
40+
<strong>Explanation:</strong>
4141
- For the first round, we divide s into groups of size 3: &quot;111&quot;, &quot;112&quot;, &quot;222&quot;, and &quot;23&quot;.
42-
​​​​​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.
42+
​​​​​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.
4343
&nbsp; So, s becomes &quot;3&quot; + &quot;4&quot; + &quot;6&quot; + &quot;5&quot; = &quot;3465&quot; after the first round.
4444
- For the second round, we divide s into &quot;346&quot; and &quot;5&quot;.
45-
&nbsp; Then we calculate the digit sum of each group: 3 + 4 + 6 = 13, 5 = 5.
46-
&nbsp; So, s becomes &quot;13&quot; + &quot;5&quot; = &quot;135&quot; after second round.
45+
&nbsp; Then we calculate the digit sum of each group: 3 + 4 + 6 = 13, 5 = 5.
46+
&nbsp; So, s becomes &quot;13&quot; + &quot;5&quot; = &quot;135&quot; after second round.
4747
Now, s.length &lt;= k, so we return &quot;135&quot; as the answer.
4848
</pre>
4949

@@ -52,9 +52,9 @@ Now, s.length &lt;= k, so we return &quot;135&quot; as the answer.
5252
<pre>
5353
<strong>Input:</strong> s = &quot;00000000&quot;, k = 3
5454
<strong>Output:</strong> &quot;000&quot;
55-
<strong>Explanation:</strong>
55+
<strong>Explanation:</strong>
5656
We divide s into &quot;000&quot;, &quot;000&quot;, and &quot;00&quot;.
57-
Then we calculate the digit sum of each group: 0 + 0 + 0 = 0, 0 + 0 + 0 = 0, and 0 + 0 = 0.
57+
Then we calculate the digit sum of each group: 0 + 0 + 0 = 0, 0 + 0 + 0 = 0, and 0 + 0 = 0.
5858
s becomes &quot;0&quot; + &quot;0&quot; + &quot;0&quot; = &quot;000&quot;, whose length is equal to k, so we return &quot;000&quot;.
5959
</pre>
6060

@@ -180,28 +180,4 @@ function digitSum(s: string, k: number): string {
180180

181181
<!-- solution:end -->
182182

183-
<!-- solution:start -->
184-
185-
### Solution 2
186-
187-
<!-- tabs:start -->
188-
189-
#### Python3
190-
191-
```python
192-
class Solution:
193-
def digitSum(self, s: str, k: int) -> str:
194-
if len(s) <= k:
195-
return s
196-
t = []
197-
while s:
198-
t.append(str(sum(int(v) for v in s[:k])))
199-
s = s[k:]
200-
return self.digitSum(''.join(t), k)
201-
```
202-
203-
<!-- tabs:end -->
204-
205-
<!-- solution:end -->
206-
207183
<!-- problem:end -->

solution/2200-2299/2243.Calculate Digit Sum of a String/Solution2.py

-9
This file was deleted.

solution/2900-2999/2920.Maximum Points After Collecting Coins From All Nodes/README.md

+4-5
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ tags:
4141
<img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/solution/2900-2999/2920.Maximum%20Points%20After%20Collecting%20Coins%20From%20All%20Nodes/images/ex1-copy.png" style="width: 60px; height: 316px; padding: 10px; background: rgb(255, 255, 255); border-radius: 0.5rem;" />
4242
<pre>
4343
<strong>输入:</strong>edges = [[0,1],[1,2],[2,3]], coins = [10,10,3,3], k = 5
44-
<strong>输出:</strong>11
44+
<strong>输出:</strong>11
4545
<strong>解释:</strong>
4646
使用第一种方法收集节点 0 上的所有金币。总积分 = 10 - 5 = 5 。
4747
使用第一种方法收集节点 1 上的所有金币。总积分 = 5 + (10 - 5) = 10 。
4848
使用第二种方法收集节点 2 上的所有金币。所以节点 3 上的金币将会变为 floor(3 / 2) = 1 ,总积分 = 10 + floor(3 / 2) = 11 。
4949
使用第二种方法收集节点 3 上的所有金币。总积分 = 11 + floor(1 / 2) = 11.
50-
可以证明收集所有节点上的金币能获得的最大积分是 11 。
50+
可以证明收集所有节点上的金币能获得的最大积分是 11 。
5151
</pre>
5252

5353
<p><strong class="example">示例 2:</strong></p>
@@ -93,8 +93,7 @@ tags:
9393

9494
最后,我们返回当前节点使用两种方法中能获得的最大积分。
9595

96-
为了避免重复计算,我们使用记忆化搜索的方法,将 $dfs(i, fa, j)$ 的结果存储到 $f[i][j]$ 中,其中 $f[i][j]$ 表示当前节点为 $i$,父节点为 $fa$,当前节点的金币数需要右移 $j$ 位,所能获得的最大积分。
97-
96+
为了避免重复计算,我们使用记忆化搜索的方法,将 $dfs(i, fa, j)$ 的结果存储到 $f[i][j]$ 中,其中 $f[i][j]$ 表示当前节点为 $i$,父节点为 $fa$,当前节点的金币数需要右移 $j$ 位,所能获得的最大
9897
时间复杂度 $O(n \times \log M)$,空间复杂度 $O(n \times \log M)$。其中 $M$ 表示 $coins[i]$ 的最大值。
9998

10099
<!-- tabs:start -->
@@ -183,7 +182,7 @@ public:
183182
g[a].emplace_back(b);
184183
g[b].emplace_back(a);
185184
}
186-
function<int(int, int, int)> dfs = [&](int i, int fa, int j) {
185+
auto dfs = [&](this auto&& dfs, int i, int fa, int j) -> int {
187186
if (f[i][j] != -1) {
188187
return f[i][j];
189188
}

solution/2900-2999/2920.Maximum Points After Collecting Coins From All Nodes/README_EN.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ tags:
4040
<img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/solution/2900-2999/2920.Maximum%20Points%20After%20Collecting%20Coins%20From%20All%20Nodes/images/ex1-copy.png" style="width: 60px; height: 316px; padding: 10px; background: rgb(255, 255, 255); border-radius: 0.5rem;" />
4141
<pre>
4242
<strong>Input:</strong> edges = [[0,1],[1,2],[2,3]], coins = [10,10,3,3], k = 5
43-
<strong>Output:</strong> 11
44-
<strong>Explanation:</strong>
43+
<strong>Output:</strong> 11
44+
<strong>Explanation:</strong>
4545
Collect all the coins from node 0 using the first way. Total points = 10 - 5 = 5.
4646
Collect all the coins from node 1 using the first way. Total points = 5 + (10 - 5) = 10.
4747
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.
4848
Collect all the coins from node 3 using the second way. Total points = 11 + floor(1 / 2) = 11.
49-
It can be shown that the maximum points we can get after collecting coins from all the nodes is 11.
49+
It can be shown that the maximum points we can get after collecting coins from all the nodes is 11.
5050
</pre>
5151

5252
<p><strong class="example">Example 2:</strong></p>
@@ -55,7 +55,7 @@ It can be shown that the maximum points we can get after collecting coins from a
5555
<pre>
5656
<strong>Input:</strong> edges = [[0,1],[0,2]], coins = [8,4,4], k = 0
5757
<strong>Output:</strong> 16
58-
<strong>Explanation:</strong>
58+
<strong>Explanation:</strong>
5959
Coins will be collected from all the nodes using the first way. Therefore, total points = (8 - 0) + (4 - 0) + (4 - 0) = 16.
6060
</pre>
6161

@@ -181,7 +181,7 @@ public:
181181
g[a].emplace_back(b);
182182
g[b].emplace_back(a);
183183
}
184-
function<int(int, int, int)> dfs = [&](int i, int fa, int j) {
184+
auto dfs = [&](this auto&& dfs, int i, int fa, int j) -> int {
185185
if (f[i][j] != -1) {
186186
return f[i][j];
187187
}

solution/2900-2999/2920.Maximum Points After Collecting Coins From All Nodes/Solution.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class Solution {
1010
g[a].emplace_back(b);
1111
g[b].emplace_back(a);
1212
}
13-
function<int(int, int, int)> dfs = [&](int i, int fa, int j) {
13+
auto dfs = [&](this auto&& dfs, int i, int fa, int j) -> int {
1414
if (f[i][j] != -1) {
1515
return f[i][j];
1616
}
@@ -28,4 +28,4 @@ class Solution {
2828
};
2929
return dfs(0, -1, 0);
3030
}
31-
};
31+
};

0 commit comments

Comments
 (0)