Skip to content

Commit 2b668d1

Browse files
committed
feat: add solutions to lc problem: No.0115
No.0115.Distinct Subsequences
1 parent 3153d62 commit 2b668d1

File tree

6 files changed

+105
-23
lines changed

6 files changed

+105
-23
lines changed

solution/0100-0199/0115.Distinct Subsequences/README.md

+48-7
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,25 @@
5252

5353
<!-- 这里可写通用的实现逻辑 -->
5454

55-
动态规划,`dp[i][j]` 表示 `s[:i]` 的子序列中 `t[:j]` 的出现次数
55+
**方法一:动态规划**
56+
57+
定义 `dp[i][j]` 表示 `s[0..i]` 的子序列中 `t[0..j]` 出现的个数。初始时 `dp[i][0]=1`,表示空串是任意字符串的子序列。答案为 `dp[m][n]`
58+
59+
`s[i] == t[j]` 时,`dp[i][j] = dp[i-1][j-1] + dp[i-1][j]`,即 `s[0..i]` 的子序列中 `t[0..j]` 出现的个数等于 `s[0..i-1]` 的子序列中 `t[0..j-1]` 出现的个数加上 `s[0..i-1]` 的子序列中 `t[0..j]` 出现的个数。
60+
61+
`s[i] != t[j]` 时,`dp[i][j] = dp[i-1][j]`,即 `s[0..i]` 的子序列中 `t[0..j]` 出现的个数等于 `s[0..i-1]` 的子序列中 `t[0..j]` 出现的个数。
62+
63+
因此,可以得到状态转移方程:
64+
65+
$$
66+
dp[i][j]=
67+
\begin{cases}
68+
dp[i-1][j-1]+dp[i-1][j], & s[i]=t[j] \\
69+
dp[i-1][j], & s[i]\neq t[j]
70+
\end{cases}
71+
$$
72+
73+
时间复杂度 $O(m\times n)$,空间复杂度 $O(m\times n)$。其中 $m$, $n$ 分别是字符串 `s``t` 的长度。
5674

5775
<!-- tabs:start -->
5876

@@ -82,15 +100,14 @@ class Solution:
82100
```java
83101
class Solution {
84102
public int numDistinct(String s, String t) {
85-
int m = s.length();
86-
int n = t.length();
103+
int m = s.length(), n = t.length();
87104
int[][] dp = new int[m + 1][n + 1];
88-
for (int i = 0; i <= m; i++) {
105+
for (int i = 0; i <= m; ++i) {
89106
dp[i][0] = 1;
90107
}
91-
for (int i = 1; i <= m; i++) {
92-
for (int j = 1; j <= n; j++) {
93-
dp[i][j] = dp[i - 1][j];
108+
for (int i = 1; i <= m; ++i) {
109+
for (int j = 1; j <= n; ++j) {
110+
dp[i][j] += dp[i - 1][j];
94111
if (s.charAt(i - 1) == t.charAt(j - 1)) {
95112
dp[i][j] += dp[i - 1][j - 1];
96113
}
@@ -147,6 +164,30 @@ public:
147164
};
148165
```
149166
167+
### **TypeScript**
168+
169+
```ts
170+
function numDistinct(s: string, t: string): number {
171+
const m = s.length;
172+
const n = t.length;
173+
const dp: number[][] = new Array(m + 1)
174+
.fill(0)
175+
.map(() => new Array(n + 1).fill(0));
176+
for (let i = 0; i <= m; ++i) {
177+
dp[i][0] = 1;
178+
}
179+
for (let i = 1; i <= m; ++i) {
180+
for (let j = 1; j <= n; ++j) {
181+
dp[i][j] = dp[i - 1][j];
182+
if (s.charAt(i - 1) === t.charAt(j - 1)) {
183+
dp[i][j] += dp[i - 1][j - 1];
184+
}
185+
}
186+
}
187+
return dp[m][n];
188+
}
189+
```
190+
150191
### **...**
151192

152193
```

solution/0100-0199/0115.Distinct Subsequences/README_EN.md

+29-6
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,14 @@ class Solution:
7070
```java
7171
class Solution {
7272
public int numDistinct(String s, String t) {
73-
int m = s.length();
74-
int n = t.length();
73+
int m = s.length(), n = t.length();
7574
int[][] dp = new int[m + 1][n + 1];
76-
for (int i = 0; i <= m; i++) {
75+
for (int i = 0; i <= m; ++i) {
7776
dp[i][0] = 1;
7877
}
79-
for (int i = 1; i <= m; i++) {
80-
for (int j = 1; j <= n; j++) {
81-
dp[i][j] = dp[i - 1][j];
78+
for (int i = 1; i <= m; ++i) {
79+
for (int j = 1; j <= n; ++j) {
80+
dp[i][j] += dp[i - 1][j];
8281
if (s.charAt(i - 1) == t.charAt(j - 1)) {
8382
dp[i][j] += dp[i - 1][j - 1];
8483
}
@@ -135,6 +134,30 @@ public:
135134
};
136135
```
137136
137+
### **TypeScript**
138+
139+
```ts
140+
function numDistinct(s: string, t: string): number {
141+
const m = s.length;
142+
const n = t.length;
143+
const dp: number[][] = new Array(m + 1)
144+
.fill(0)
145+
.map(() => new Array(n + 1).fill(0));
146+
for (let i = 0; i <= m; ++i) {
147+
dp[i][0] = 1;
148+
}
149+
for (let i = 1; i <= m; ++i) {
150+
for (let j = 1; j <= n; ++j) {
151+
dp[i][j] = dp[i - 1][j];
152+
if (s.charAt(i - 1) === t.charAt(j - 1)) {
153+
dp[i][j] += dp[i - 1][j - 1];
154+
}
155+
}
156+
}
157+
return dp[m][n];
158+
}
159+
```
160+
138161
### **...**
139162

140163
```

solution/0100-0199/0115.Distinct Subsequences/Solution.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ class Solution {
1616
}
1717
return dp[m][n];
1818
}
19-
};
19+
};
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
class Solution {
22
public int numDistinct(String s, String t) {
3-
int m = s.length();
4-
int n = t.length();
3+
int m = s.length(), n = t.length();
54
int[][] dp = new int[m + 1][n + 1];
6-
for (int i = 0; i <= m; i++) {
5+
for (int i = 0; i <= m; ++i) {
76
dp[i][0] = 1;
87
}
9-
for (int i = 1; i <= m; i++) {
10-
for (int j = 1; j <= n; j++) {
11-
dp[i][j] = dp[i - 1][j];
8+
for (int i = 1; i <= m; ++i) {
9+
for (int j = 1; j <= n; ++j) {
10+
dp[i][j] += dp[i - 1][j];
1211
if (s.charAt(i - 1) == t.charAt(j - 1)) {
1312
dp[i][j] += dp[i - 1][j - 1];
1413
}
1514
}
1615
}
1716
return dp[m][n];
1817
}
19-
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
class Solution:
22
def numDistinct(self, s: str, t: str) -> int:
33
m, n = len(s), len(t)
4-
dp = [[0] * n + 1 for _ in range(m + 1)]
4+
dp = [[0] * (n + 1) for _ in range(m + 1)]
55
for i in range(m + 1):
66
dp[i][0] = 1
77
for i in range(1, m + 1):
88
for j in range(1, n + 1):
99
dp[i][j] = dp[i - 1][j]
10-
if s[i - 1] == s[j - 1]:
10+
if s[i - 1] == t[j - 1]:
1111
dp[i][j] += dp[i - 1][j - 1]
1212
return dp[m][n]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
function numDistinct(s: string, t: string): number {
2+
const m = s.length;
3+
const n = t.length;
4+
const dp: number[][] = new Array(m + 1)
5+
.fill(0)
6+
.map(() => new Array(n + 1).fill(0));
7+
for (let i = 0; i <= m; ++i) {
8+
dp[i][0] = 1;
9+
}
10+
for (let i = 1; i <= m; ++i) {
11+
for (let j = 1; j <= n; ++j) {
12+
dp[i][j] = dp[i - 1][j];
13+
if (s.charAt(i - 1) === t.charAt(j - 1)) {
14+
dp[i][j] += dp[i - 1][j - 1];
15+
}
16+
}
17+
}
18+
return dp[m][n];
19+
}

0 commit comments

Comments
 (0)