Skip to content

Commit 6a8ce4b

Browse files
authored
feat: add solutions to lc problem: No.1955 (doocs#1359)
No.1955.Count Number of Special Subsequences
1 parent 48da787 commit 6a8ce4b

File tree

7 files changed

+594
-0
lines changed

7 files changed

+594
-0
lines changed

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

+266
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,288 @@
6363

6464
<!-- 这里可写通用的实现逻辑 -->
6565

66+
**方法一:动态规划**
67+
68+
我们定义 $f[i][j]$ 表示前 $i+1$ 个元素中,以 $j$ 结尾的特殊子序列的个数。初始时 $f[i][j]=0$,如果 $nums[0]=0$,则 $f[0][0]=1$。
69+
70+
对于 $i \gt 0$,我们考虑 $nums[i]$ 的值:
71+
72+
如果 $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]$ 相等。
73+
74+
如果 $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]$ 相等。
75+
76+
如果 $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]$ 相等。
77+
78+
综上,我们可以得到如下的状态转移方程:
79+
80+
$$
81+
\begin{aligned}
82+
f[i][0] &= 2 \times f[i - 1][0] + 1, \quad nums[i] = 0 \\
83+
f[i][1] &= f[i-1][1] + 2 \times f[i - 1][0], \quad nums[i] = 1 \\
84+
f[i][2] &= f[i-1][2] + 2 \times f[i - 1][1], \quad nums[i] = 2 \\
85+
f[i][j] &= f[i-1][j], \quad nums[i] \neq j
86+
\end{aligned}
87+
$$
88+
89+
最终的答案即为 $f[n-1][2]$。
90+
91+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $nums$ 的长度。
92+
93+
我们注意到,上述的状态转移方程中,$f[i][j]$ 的值仅与 $f[i-1][j]$ 有关,因此我们可以去掉第一维,将空间复杂度优化到 $O(1)$。
94+
6695
<!-- tabs:start -->
6796

6897
### **Python3**
6998

7099
<!-- 这里可写当前语言的特殊实现逻辑 -->
71100

72101
```python
102+
class Solution:
103+
def countSpecialSubsequences(self, nums: List[int]) -> int:
104+
mod = 10**9 + 7
105+
n = len(nums)
106+
f = [[0] * 3 for _ in range(n)]
107+
f[0][0] = nums[0] == 0
108+
for i in range(1, n):
109+
if nums[i] == 0:
110+
f[i][0] = (2 * f[i - 1][0] + 1) % mod
111+
f[i][1] = f[i - 1][1]
112+
f[i][2] = f[i - 1][2]
113+
elif nums[i] == 1:
114+
f[i][0] = f[i - 1][0]
115+
f[i][1] = (f[i - 1][0] + 2 * f[i - 1][1]) % mod
116+
f[i][2] = f[i - 1][2]
117+
else:
118+
f[i][0] = f[i - 1][0]
119+
f[i][1] = f[i - 1][1]
120+
f[i][2] = (f[i - 1][1] + 2 * f[i - 1][2]) % mod
121+
return f[n - 1][2]
122+
```
73123

124+
```python
125+
class Solution:
126+
def countSpecialSubsequences(self, nums: List[int]) -> int:
127+
mod = 10**9 + 7
128+
n = len(nums)
129+
f = [0] * 3
130+
f[0] = nums[0] == 0
131+
for i in range(1, n):
132+
if nums[i] == 0:
133+
f[0] = (2 * f[0] + 1) % mod
134+
elif nums[i] == 1:
135+
f[1] = (f[0] + 2 * f[1]) % mod
136+
else:
137+
f[2] = (f[1] + 2 * f[2]) % mod
138+
return f[2]
74139
```
75140

76141
### **Java**
77142

78143
<!-- 这里可写当前语言的特殊实现逻辑 -->
79144

80145
```java
146+
class Solution {
147+
public int countSpecialSubsequences(int[] nums) {
148+
final int mod = (int) 1e9 + 7;
149+
int n = nums.length;
150+
int[][] f = new int[n][3];
151+
f[0][0] = nums[0] == 0 ? 1 : 0;
152+
for (int i = 1; i < n; ++i) {
153+
if (nums[i] == 0) {
154+
f[i][0] = (2 * f[i - 1][0] % mod + 1) % mod;
155+
f[i][1] = f[i - 1][1];
156+
f[i][2] = f[i - 1][2];
157+
} else if (nums[i] == 1) {
158+
f[i][0] = f[i - 1][0];
159+
f[i][1] = (f[i - 1][0] + 2 * f[i - 1][1] % mod) % mod;
160+
f[i][2] = f[i - 1][2];
161+
} else {
162+
f[i][0] = f[i - 1][0];
163+
f[i][1] = f[i - 1][1];
164+
f[i][2] = (f[i - 1][1] + 2 * f[i - 1][2] % mod) % mod;
165+
}
166+
}
167+
return f[n - 1][2];
168+
}
169+
}
170+
```
171+
172+
```java
173+
class Solution {
174+
public int countSpecialSubsequences(int[] nums) {
175+
final int mod = (int) 1e9 + 7;
176+
int n = nums.length;
177+
int[] f = new int[3];
178+
f[0] = nums[0] == 0 ? 1 : 0;
179+
for (int i = 1; i < n; ++i) {
180+
if (nums[i] == 0) {
181+
f[0] = (2 * f[0] % mod + 1) % mod;
182+
} else if (nums[i] == 1) {
183+
f[1] = (f[0] + 2 * f[1] % mod) % mod;
184+
} else {
185+
f[2] = (f[1] + 2 * f[2] % mod) % mod;
186+
}
187+
}
188+
return f[2];
189+
}
190+
}
191+
```
192+
193+
### **C++**
194+
195+
```cpp
196+
class Solution {
197+
public:
198+
int countSpecialSubsequences(vector<int>& nums) {
199+
const int mod = 1e9 + 7;
200+
int n = nums.size();
201+
int f[n][3];
202+
memset(f, 0, sizeof(f));
203+
f[0][0] = nums[0] == 0;
204+
for (int i = 1; i < n; ++i) {
205+
if (nums[i] == 0) {
206+
f[i][0] = (2 * f[i - 1][0] % mod + 1) % mod;
207+
f[i][1] = f[i - 1][1];
208+
f[i][2] = f[i - 1][2];
209+
} else if (nums[i] == 1) {
210+
f[i][0] = f[i - 1][0];
211+
f[i][1] = (f[i - 1][0] + 2 * f[i - 1][1] % mod) % mod;
212+
f[i][2] = f[i - 1][2];
213+
} else {
214+
f[i][0] = f[i - 1][0];
215+
f[i][1] = f[i - 1][1];
216+
f[i][2] = (f[i - 1][1] + 2 * f[i - 1][2] % mod) % mod;
217+
}
218+
}
219+
return f[n - 1][2];
220+
}
221+
};
222+
```
223+
224+
```cpp
225+
class Solution {
226+
public:
227+
int countSpecialSubsequences(vector<int>& nums) {
228+
const int mod = 1e9 + 7;
229+
int n = nums.size();
230+
int f[3]{0};
231+
f[0] = nums[0] == 0;
232+
for (int i = 1; i < n; ++i) {
233+
if (nums[i] == 0) {
234+
f[0] = (2 * f[0] % mod + 1) % mod;
235+
} else if (nums[i] == 1) {
236+
f[1] = (f[0] + 2 * f[1] % mod) % mod;
237+
} else {
238+
f[2] = (f[1] + 2 * f[2] % mod) % mod;
239+
}
240+
}
241+
return f[2];
242+
}
243+
};
244+
```
245+
246+
### **Go**
247+
248+
```go
249+
func countSpecialSubsequences(nums []int) int {
250+
const mod = 1e9 + 7
251+
n := len(nums)
252+
f := make([][3]int, n)
253+
if nums[0] == 0 {
254+
f[0][0] = 1
255+
}
256+
for i := 1; i < n; i++ {
257+
if nums[i] == 0 {
258+
f[i][0] = (2*f[i-1][0] + 1) % mod
259+
f[i][1] = f[i-1][1]
260+
f[i][2] = f[i-1][2]
261+
} else if nums[i] == 1 {
262+
f[i][0] = f[i-1][0]
263+
f[i][1] = (f[i-1][0] + 2*f[i-1][1]) % mod
264+
f[i][2] = f[i-1][2]
265+
} else {
266+
f[i][0] = f[i-1][0]
267+
f[i][1] = f[i-1][1]
268+
f[i][2] = (f[i-1][1] + 2*f[i-1][2]) % mod
269+
}
270+
}
271+
return f[n-1][2]
272+
}
273+
```
274+
275+
```go
276+
func countSpecialSubsequences(nums []int) int {
277+
const mod = 1e9 + 7
278+
n := len(nums)
279+
f := [3]int{}
280+
if nums[0] == 0 {
281+
f[0] = 1
282+
}
283+
for i := 1; i < n; i++ {
284+
if nums[i] == 0 {
285+
f[0] = (2*f[0] + 1) % mod
286+
} else if nums[i] == 1 {
287+
f[1] = (f[0] + 2*f[1]) % mod
288+
} else {
289+
f[2] = (f[1] + 2*f[2]) % mod
290+
}
291+
}
292+
return f[2]
293+
}
294+
```
295+
296+
### **TypeScript**
297+
298+
```ts
299+
function countSpecialSubsequences(nums: number[]): number {
300+
const mod = 1e9 + 7;
301+
const n = nums.length;
302+
const f: number[][] = Array(n)
303+
.fill(0)
304+
.map(() => Array(3).fill(0));
305+
f[0][0] = nums[0] === 0 ? 1 : 0;
306+
for (let i = 1; i < n; ++i) {
307+
if (nums[i] === 0) {
308+
f[i][0] = (((2 * f[i - 1][0]) % mod) + 1) % mod;
309+
f[i][1] = f[i - 1][1];
310+
f[i][2] = f[i - 1][2];
311+
} else if (nums[i] === 1) {
312+
f[i][0] = f[i - 1][0];
313+
f[i][1] = (f[i - 1][0] + ((2 * f[i - 1][1]) % mod)) % mod;
314+
f[i][2] = f[i - 1][2];
315+
} else {
316+
f[i][0] = f[i - 1][0];
317+
f[i][1] = f[i - 1][1];
318+
f[i][2] = (f[i - 1][1] + ((2 * f[i - 1][2]) % mod)) % mod;
319+
}
320+
}
321+
return f[n - 1][2];
322+
}
323+
```
81324

325+
```ts
326+
function countSpecialSubsequences(nums: number[]): number {
327+
const mod = 1e9 + 7;
328+
const n = nums.length;
329+
const f: number[] = [0, 0, 0];
330+
f[0] = nums[0] === 0 ? 1 : 0;
331+
for (let i = 1; i < n; ++i) {
332+
if (nums[i] === 0) {
333+
f[0] = (((2 * f[0]) % mod) + 1) % mod;
334+
f[1] = f[1];
335+
f[2] = f[2];
336+
} else if (nums[i] === 1) {
337+
f[0] = f[0];
338+
f[1] = (f[0] + ((2 * f[1]) % mod)) % mod;
339+
f[2] = f[2];
340+
} else {
341+
f[0] = f[0];
342+
f[1] = f[1];
343+
f[2] = (f[1] + ((2 * f[2]) % mod)) % mod;
344+
}
345+
}
346+
return f[2];
347+
}
82348
```
83349

84350
### **...**

0 commit comments

Comments
 (0)