Skip to content

Commit 1ea1077

Browse files
authored
fix: update solutions to lc problem: No.1955 (#4257)
close #4256
1 parent 6c6cb55 commit 1ea1077

File tree

2 files changed

+42
-9
lines changed

2 files changed

+42
-9
lines changed

solution/1900-1999/1955.Count Number of Special Subsequences/README.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -86,17 +86,17 @@ tags:
8686

8787
如果 $nums[i] = 0$:如果我们不选择 $nums[i]$,则 $f[i][0] = f[i-1][0]$;如果我们选择 $nums[i]$,那么 $f[i][0]=f[i-1][0]+1$,因为我们可以在任何一个以 $0$ 结尾的特殊子序列后面加上一个 $0$ 得到一个新的特殊子序列,也可以将 $nums[i]$ 单独作为一个特殊子序列。因此 $f[i][0] = 2 \times f[i - 1][0] + 1$。其余的 $f[i][j]$ 与 $f[i-1][j]$ 相等。
8888

89-
如果 $nums[i] = 1$:如果我们不选择 $nums[i]$,则 $f[i][1] = f[i-1][1]$;如果我们选择 $nums[i]$,那么 $f[i][1]=f[i-1][1]+f[i-1][0]$,因为我们可以在任何一个以 $0$ 或 $1$ 结尾的特殊子序列后面加上一个 $1$ 得到一个新的特殊子序列。因此 $f[i][1] = f[i-1][1] + 2 \times f[i - 1][0]$。其余的 $f[i][j]$ 与 $f[i-1][j]$ 相等。
89+
如果 $nums[i] = 1$:如果我们不选择 $nums[i]$,则 $f[i][1] = f[i-1][1]$;如果我们选择 $nums[i]$,那么 $f[i][1]=f[i-1][1]+f[i-1][0]$,因为我们可以在任何一个以 $0$ 或 $1$ 结尾的特殊子序列后面加上一个 $1$ 得到一个新的特殊子序列。因此 $f[i][1] = f[i-1][0] + 2 \times f[i - 1][1]$。其余的 $f[i][j]$ 与 $f[i-1][j]$ 相等。
9090

91-
如果 $nums[i] = 2$:如果我们不选择 $nums[i]$,则 $f[i][2] = f[i-1][2]$;如果我们选择 $nums[i]$,那么 $f[i][2]=f[i-1][2]+f[i-1][1]$,因为我们可以在任何一个以 $1$ 或 $2$ 结尾的特殊子序列后面加上一个 $2$ 得到一个新的特殊子序列。因此 $f[i][2] = f[i-1][2] + 2 \times f[i - 1][1]$。其余的 $f[i][j]$ 与 $f[i-1][j]$ 相等。
91+
如果 $nums[i] = 2$:如果我们不选择 $nums[i]$,则 $f[i][2] = f[i-1][2]$;如果我们选择 $nums[i]$,那么 $f[i][2]=f[i-1][2]+f[i-1][1]$,因为我们可以在任何一个以 $1$ 或 $2$ 结尾的特殊子序列后面加上一个 $2$ 得到一个新的特殊子序列。因此 $f[i][2] = f[i-1][1] + 2 \times f[i - 1][2]$。其余的 $f[i][j]$ 与 $f[i-1][j]$ 相等。
9292

9393
综上,我们可以得到如下的状态转移方程:
9494

9595
$$
9696
\begin{aligned}
9797
f[i][0] &= 2 \times f[i - 1][0] + 1, \quad nums[i] = 0 \\
98-
f[i][1] &= f[i-1][1] + 2 \times f[i - 1][0], \quad nums[i] = 1 \\
99-
f[i][2] &= f[i-1][2] + 2 \times f[i - 1][1], \quad nums[i] = 2 \\
98+
f[i][1] &= f[i-1][0] + 2 \times f[i - 1][1], \quad nums[i] = 1 \\
99+
f[i][2] &= f[i-1][1] + 2 \times f[i - 1][2], \quad nums[i] = 2 \\
100100
f[i][j] &= f[i-1][j], \quad nums[i] \neq j
101101
\end{aligned}
102102
$$
@@ -105,8 +105,6 @@ $$
105105

106106
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $nums$ 的长度。
107107

108-
我们注意到,上述的状态转移方程中,$f[i][j]$ 的值仅与 $f[i-1][j]$ 有关,因此我们可以去掉第一维,将空间复杂度优化到 $O(1)$。
109-
110108
<!-- tabs:start -->
111109

112110
#### Python3
@@ -258,7 +256,9 @@ function countSpecialSubsequences(nums: number[]): number {
258256

259257
<!-- solution:start -->
260258

261-
### 方法二
259+
### 方法二:动态规划(空间优化)
260+
261+
我们注意到,上述的状态转移方程中,$f[i][j]$ 的值仅与 $f[i-1][j]$ 有关,因此我们可以去掉第一维,将空间复杂度优化到 $O(1)$。
262262

263263
<!-- tabs:start -->
264264

solution/1900-1999/1955.Count Number of Special Subsequences/README_EN.md

+35-2
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,34 @@ tags:
7676

7777
<!-- solution:start -->
7878

79-
### Solution 1
79+
### Solution 1: Dynamic Programming
80+
81+
We define $f[i][j]$ to represent the number of special subsequences ending with $j$ among the first $i+1$ elements. Initially, $f[i][j]=0$, and if $nums[0]=0$, then $f[0][0]=1$.
82+
83+
For $i \gt 0$, we consider the value of $nums[i]$:
84+
85+
If $nums[i] = 0$: If we do not choose $nums[i]$, then $f[i][0] = f[i-1][0]$; if we choose $nums[i]$, then $f[i][0]=f[i-1][0]+1$, because we can add a $0$ to the end of any special subsequence ending with $0$ to get a new special subsequence, or we can use $nums[i]$ alone as a special subsequence. Therefore, $f[i][0] = 2 \times f[i - 1][0] + 1$. The rest of $f[i][j]$ is equal to $f[i-1][j]$.
86+
87+
If $nums[i] = 1$: If we do not choose $nums[i]$, then $f[i][1] = f[i-1][1]$; if we choose $nums[i]$, then $f[i][1]=f[i-1][1]+f[i-1][0]$, because we can add a $1$ to the end of any special subsequence ending with $0$ or $1$ to get a new special subsequence. Therefore, $f[i][1] = f[i-1][0] + 2 \times f[i - 1][1]$. The rest of $f[i][j]$ is equal to $f[i-1][j]$.
88+
89+
If $nums[i] = 2$: If we do not choose $nums[i]$, then $f[i][2] = f[i-1][2]$; if we choose $nums[i]$, then $f[i][2]=f[i-1][2]+f[i-1][1]$, because we can add a $2$ to the end of any special subsequence ending with $1$ or $2$ to get a new special subsequence. Therefore, $f[i][2] = f[i-1][1] + 2 \times f[i - 1][2]$. The rest of $f[i][j]$ is equal to $f[i-1][j]$.
90+
91+
In summary, we can get the following state transition equations:
92+
93+
$$
94+
\begin{aligned}
95+
f[i][0] &= 2 \times f[i - 1][0] + 1, \quad nums[i] = 0 \\
96+
f[i][1] &= f[i-1][0] + 2 \times f[i - 1][1], \quad nums[i] = 1 \\
97+
f[i][2] &= f[i-1][1] + 2 \times f[i - 1][2], \quad nums[i] = 2 \\
98+
f[i][j] &= f[i-1][j], \quad nums[i] \neq j
99+
\end{aligned}
100+
$$
101+
102+
The final answer is $f[n-1][2]$.
103+
104+
The time complexity is $O(n)$, and the space complexity is $O(n)$. Where $n$ is the length of the array $nums$.
105+
106+
Similar code found with 1 license type
80107

81108
<!-- tabs:start -->
82109

@@ -229,7 +256,13 @@ function countSpecialSubsequences(nums: number[]): number {
229256

230257
<!-- solution:start -->
231258

232-
### Solution 2
259+
### Solution 2: Dynamic Programming (Space Optimization)
260+
261+
We notice that in the above state transition equations, the value of $f[i][j]$ is only related to $f[i-1][j]$. Therefore, we can remove the first dimension and optimize the space complexity to $O(1)$.
262+
263+
We can use an array $f$ of length 3 to represent the number of special subsequences ending with 0, 1, and 2, respectively. For each element in the array, we update the array $f$ according to the value of the current element.
264+
265+
The time complexity is $O(n)$, and the space complexity is $O(1)$. Where $n$ is the length of the array $nums$.
233266

234267
<!-- tabs:start -->
235268

0 commit comments

Comments
 (0)