Skip to content

Commit 81a80c8

Browse files
committed
feat: add solutions to lc/lcof2 problems
* lc No.0712.Minimum ASCII Delete Sum for Two Strings * lcof2 No.095.Longest Common Subsequence
1 parent 2ff09a5 commit 81a80c8

File tree

11 files changed

+305
-3
lines changed

11 files changed

+305
-3
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@
7474
- [俄罗斯套娃信封问题](/solution/0300-0399/0354.Russian%20Doll%20Envelopes/README.md) - 线性 DP、最长上升子序列模型、贪心优化
7575
- [堆叠长方体的最大高度](/solution/1600-1699/1691.Maximum%20Height%20by%20Stacking%20Cuboids/README.md) - 排序、线性 DP、最长上升子序列模型
7676
- [无矛盾的最佳球队](/solution/1600-1699/1626.Best%20Team%20With%20No%20Conflicts/README.md) - 排序、线性 DP、最长上升子序列模型
77+
- [最长公共子序列](/solution/1100-1199/1143.Longest%20Common%20Subsequence/README.md) - 线性 DP、最长公共子序列模型
78+
- [两个字符串的最小 ASCII 删除和](/solution/0700-0799/0712.Minimum%20ASCII%20Delete%20Sum%20for%20Two%20Strings/README.md) - 线性 DP、最长公共子序列模型
7779
<!-- 背包问题、状态机模型、状压DP、区间DP、树形DP、数位DP 待补充 -->
7880

7981
### 4. 高级数据结构

README_EN.md

+2
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ Complete solutions to [LeetCode](https://leetcode.com/problemset/all/), [LCOF](h
7171
- [Russian Doll Envelopes](/solution/0300-0399/0354.Russian%20Doll%20Envelopes/README_EN.md) - Linear problem, LIS
7272
- [Maximum Height by Stacking Cuboids](/solution/1600-1699/1691.Maximum%20Height%20by%20Stacking%20Cuboids/README_EN.md) - Sort, Linear problem, LIS
7373
- [Best Team With No Conflicts](/solution/1600-1699/1626.Best%20Team%20With%20No%20Conflicts/README_EN.md) - Sort, Linear problem, LIS
74+
- [Longest Common Subsequence](/solution/1100-1199/1143.Longest%20Common%20Subsequence/README_EN.md) - Linear problem, LCS
75+
- [Minimum ASCII Delete Sum for Two Strings](/solution/0700-0799/0712.Minimum%20ASCII%20Delete%20Sum%20for%20Two%20Strings/README_EN.md) - Linear problem, LCS
7476

7577
### 4. Advanced Data Structures
7678

lcof2/剑指 Offer II 095. 最长公共子序列/README.md

+28-1
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,16 @@
5757

5858
<!-- 这里可写通用的实现逻辑 -->
5959

60-
动态规划法。
60+
**方法一:动态规划**
6161

6262
定义 `dp[i][j]` 表示 `text1[0:i-1]``text2[0:j-1]` 的最长公共子序列(闭区间)。
6363

6464
递推公式如下:
6565

6666
![](https://cdn.jsdelivr.net/gh/doocs/leetcode@main/lcof2/剑指%20Offer%20II%20095.%20最长公共子序列/images/gif.gif)
6767

68+
时间复杂度 O(mn)。
69+
6870
<!-- tabs:start -->
6971

7072
### **Python3**
@@ -164,6 +166,31 @@ func max(a, b int) int {
164166
}
165167
```
166168

169+
### **JavaScript**
170+
171+
```js
172+
/**
173+
* @param {string} text1
174+
* @param {string} text2
175+
* @return {number}
176+
*/
177+
var longestCommonSubsequence = function (text1, text2) {
178+
const m = text1.length;
179+
const n = text2.length;
180+
const dp = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0));
181+
for (let i = 1; i <= m; ++i) {
182+
for (let j = 1; j <= n; ++j) {
183+
if (text1[i - 1] == text2[j - 1]) {
184+
dp[i][j] = dp[i - 1][j - 1] + 1;
185+
} else {
186+
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
187+
}
188+
}
189+
}
190+
return dp[m][n];
191+
};
192+
```
193+
167194
### **...**
168195

169196
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* @param {string} text1
3+
* @param {string} text2
4+
* @return {number}
5+
*/
6+
var longestCommonSubsequence = function (text1, text2) {
7+
const m = text1.length;
8+
const n = text2.length;
9+
const dp = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0));
10+
for (let i = 1; i <= m; ++i) {
11+
for (let j = 1; j <= n; ++j) {
12+
if (text1[i - 1] == text2[j - 1]) {
13+
dp[i][j] = dp[i - 1][j - 1] + 1;
14+
} else {
15+
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
16+
}
17+
}
18+
}
19+
return dp[m][n];
20+
};

solution/0700-0799/0712.Minimum ASCII Delete Sum for Two Strings/README.md

+103-1
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,124 @@
4444

4545
<!-- 这里可写通用的实现逻辑 -->
4646

47+
**方法一:动态规划**
48+
49+
类似[1143. 最长公共子序列](/solution/1100-1199/1143.Longest%20Common%20Subsequence/README.md)
50+
51+
定义 `dp[i][j]` 表示使得 `s1[0:i-1]``s2[0:j-1]` 两个字符串相等所需删除的字符的 ASCII 值的最小值。
52+
53+
时间复杂度 O(mn)。
54+
4755
<!-- tabs:start -->
4856

4957
### **Python3**
5058

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

5361
```python
54-
62+
class Solution:
63+
def minimumDeleteSum(self, s1: str, s2: str) -> int:
64+
m, n = len(s1), len(s2)
65+
dp = [[0] * (n + 1) for _ in range(m + 1)]
66+
for i in range(1, m + 1):
67+
dp[i][0] = dp[i - 1][0] + ord(s1[i - 1])
68+
for j in range(1, n + 1):
69+
dp[0][j] = dp[0][j - 1] + ord(s2[j - 1])
70+
for i in range(1, m + 1):
71+
for j in range(1, n + 1):
72+
if s1[i - 1] == s2[j - 1]:
73+
dp[i][j] = dp[i - 1][j - 1]
74+
else:
75+
dp[i][j] = min(dp[i - 1][j] + ord(s1[i - 1]),
76+
dp[i][j - 1] + ord(s2[j - 1]))
77+
return dp[-1][-1]
5578
```
5679

5780
### **Java**
5881

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

6184
```java
85+
class Solution {
86+
public int minimumDeleteSum(String s1, String s2) {
87+
int m = s1.length(), n = s2.length();
88+
int[][] dp = new int[m + 1][n + 1];
89+
for (int i = 1; i <= m; ++i) {
90+
dp[i][0] = dp[i - 1][0] + s1.codePointAt(i - 1);
91+
}
92+
for (int j = 1; j <= n; ++j) {
93+
dp[0][j] = dp[0][j - 1] + s2.codePointAt(j - 1);
94+
}
95+
for (int i = 1; i <= m; ++i) {
96+
for (int j = 1; j <= n; ++j) {
97+
if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
98+
dp[i][j] = dp[i - 1][j - 1];
99+
} else {
100+
dp[i][j] = Math.min(dp[i - 1][j] + s1.codePointAt(i - 1), dp[i][j - 1] + s2.codePointAt(j - 1));
101+
}
102+
}
103+
}
104+
return dp[m][n];
105+
}
106+
}
107+
```
108+
109+
### **C++**
110+
111+
```cpp
112+
class Solution {
113+
public:
114+
int minimumDeleteSum(string s1, string s2) {
115+
int m = s1.size(), n = s2.size();
116+
vector<vector<int>> dp(m + 1, vector<int>(n + 1));
117+
for (int i = 1; i <= m; ++i) dp[i][0] = dp[i - 1][0] + s1[i - 1];
118+
for (int j = 1; j <= n; ++j) dp[0][j] = dp[0][j - 1] + s2[j - 1];
119+
for (int i = 1; i <= m; ++i)
120+
{
121+
for (int j = 1; j <= n; ++j)
122+
{
123+
if (s1[i - 1] == s2[j - 1]) dp[i][j] = dp[i - 1][j - 1];
124+
else dp[i][j] = min(dp[i - 1][j] + s1[i - 1], dp[i][j - 1] + s2[j - 1]);
125+
}
126+
}
127+
return dp[m][n];
128+
}
129+
};
130+
```
62131
132+
### **Go**
133+
134+
```go
135+
func minimumDeleteSum(s1 string, s2 string) int {
136+
m, n := len(s1), len(s2)
137+
dp := make([][]int, m+1)
138+
for i := range dp {
139+
dp[i] = make([]int, n+1)
140+
}
141+
for i := 1; i <= m; i++ {
142+
dp[i][0] = dp[i-1][0] + int(s1[i-1])
143+
}
144+
for j := 1; j <= n; j++ {
145+
dp[0][j] = dp[0][j-1] + int(s2[j-1])
146+
}
147+
for i := 1; i <= m; i++ {
148+
for j := 1; j <= n; j++ {
149+
if s1[i-1] == s2[j-1] {
150+
dp[i][j] = dp[i-1][j-1]
151+
} else {
152+
dp[i][j] = min(dp[i-1][j]+int(s1[i-1]), dp[i][j-1]+int(s2[j-1]))
153+
}
154+
}
155+
}
156+
return dp[m][n]
157+
}
158+
159+
func min(a, b int) int {
160+
if a < b {
161+
return a
162+
}
163+
return b
164+
}
63165
```
64166

65167
### **...**

solution/0700-0799/0712.Minimum ASCII Delete Sum for Two Strings/README_EN.md

+62-1
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,79 @@ If instead we turned both strings into &quot;lee&quot; or &quot;eet&quot;, we wo
3939

4040
## Solutions
4141

42+
Dynamic programming.
43+
4244
<!-- tabs:start -->
4345

4446
### **Python3**
4547

4648
```python
47-
49+
class Solution:
50+
def minimumDeleteSum(self, s1: str, s2: str) -> int:
51+
m, n = len(s1), len(s2)
52+
dp = [[0] * (n + 1) for _ in range(m + 1)]
53+
for i in range(1, m + 1):
54+
dp[i][0] = dp[i - 1][0] + ord(s1[i - 1])
55+
for j in range(1, n + 1):
56+
dp[0][j] = dp[0][j - 1] + ord(s2[j - 1])
57+
for i in range(1, m + 1):
58+
for j in range(1, n + 1):
59+
if s1[i - 1] == s2[j - 1]:
60+
dp[i][j] = dp[i - 1][j - 1]
61+
else:
62+
dp[i][j] = min(dp[i - 1][j] + ord(s1[i - 1]),
63+
dp[i][j - 1] + ord(s2[j - 1]))
64+
return dp[-1][-1]
4865
```
4966

5067
### **Java**
5168

5269
```java
70+
class Solution {
71+
public int minimumDeleteSum(String s1, String s2) {
72+
int m = s1.length(), n = s2.length();
73+
int[][] dp = new int[m + 1][n + 1];
74+
for (int i = 1; i <= m; ++i) {
75+
dp[i][0] = dp[i - 1][0] + s1.codePointAt(i - 1);
76+
}
77+
for (int j = 1; j <= n; ++j) {
78+
dp[0][j] = dp[0][j - 1] + s2.codePointAt(j - 1);
79+
}
80+
for (int i = 1; i <= m; ++i) {
81+
for (int j = 1; j <= n; ++j) {
82+
if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
83+
dp[i][j] = dp[i - 1][j - 1];
84+
} else {
85+
dp[i][j] = Math.min(dp[i - 1][j] + s1.codePointAt(i - 1), dp[i][j - 1] + s2.codePointAt(j - 1));
86+
}
87+
}
88+
}
89+
return dp[m][n];
90+
}
91+
}
92+
```
5393

94+
### **C++**
95+
96+
```cpp
97+
class Solution {
98+
public:
99+
int minimumDeleteSum(string s1, string s2) {
100+
int m = s1.size(), n = s2.size();
101+
vector<vector<int>> dp(m + 1, vector<int>(n + 1));
102+
for (int i = 1; i <= m; ++i) dp[i][0] = dp[i - 1][0] + s1[i - 1];
103+
for (int j = 1; j <= n; ++j) dp[0][j] = dp[0][j - 1] + s2[j - 1];
104+
for (int i = 1; i <= m; ++i)
105+
{
106+
for (int j = 1; j <= n; ++j)
107+
{
108+
if (s1[i - 1] == s2[j - 1]) dp[i][j] = dp[i - 1][j - 1];
109+
else dp[i][j] = min(dp[i - 1][j] + s1[i - 1], dp[i][j - 1] + s2[j - 1]);
110+
}
111+
}
112+
return dp[m][n];
113+
}
114+
};
54115
```
55116
56117
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class Solution {
2+
public:
3+
int minimumDeleteSum(string s1, string s2) {
4+
int m = s1.size(), n = s2.size();
5+
vector<vector<int>> dp(m + 1, vector<int>(n + 1));
6+
for (int i = 1; i <= m; ++i) dp[i][0] = dp[i - 1][0] + s1[i - 1];
7+
for (int j = 1; j <= n; ++j) dp[0][j] = dp[0][j - 1] + s2[j - 1];
8+
for (int i = 1; i <= m; ++i)
9+
{
10+
for (int j = 1; j <= n; ++j)
11+
{
12+
if (s1[i - 1] == s2[j - 1]) dp[i][j] = dp[i - 1][j - 1];
13+
else dp[i][j] = min(dp[i - 1][j] + s1[i - 1], dp[i][j - 1] + s2[j - 1]);
14+
}
15+
}
16+
return dp[m][n];
17+
}
18+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
func minimumDeleteSum(s1 string, s2 string) int {
2+
m, n := len(s1), len(s2)
3+
dp := make([][]int, m+1)
4+
for i := range dp {
5+
dp[i] = make([]int, n+1)
6+
}
7+
for i := 1; i <= m; i++ {
8+
dp[i][0] = dp[i-1][0] + int(s1[i-1])
9+
}
10+
for j := 1; j <= n; j++ {
11+
dp[0][j] = dp[0][j-1] + int(s2[j-1])
12+
}
13+
for i := 1; i <= m; i++ {
14+
for j := 1; j <= n; j++ {
15+
if s1[i-1] == s2[j-1] {
16+
dp[i][j] = dp[i-1][j-1]
17+
} else {
18+
dp[i][j] = min(dp[i-1][j]+int(s1[i-1]), dp[i][j-1]+int(s2[j-1]))
19+
}
20+
}
21+
}
22+
return dp[m][n]
23+
}
24+
25+
func min(a, b int) int {
26+
if a < b {
27+
return a
28+
}
29+
return b
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class Solution {
2+
public int minimumDeleteSum(String s1, String s2) {
3+
int m = s1.length(), n = s2.length();
4+
int[][] dp = new int[m + 1][n + 1];
5+
for (int i = 1; i <= m; ++i) {
6+
dp[i][0] = dp[i - 1][0] + s1.codePointAt(i - 1);
7+
}
8+
for (int j = 1; j <= n; ++j) {
9+
dp[0][j] = dp[0][j - 1] + s2.codePointAt(j - 1);
10+
}
11+
for (int i = 1; i <= m; ++i) {
12+
for (int j = 1; j <= n; ++j) {
13+
if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
14+
dp[i][j] = dp[i - 1][j - 1];
15+
} else {
16+
dp[i][j] = Math.min(dp[i - 1][j] + s1.codePointAt(i - 1), dp[i][j - 1] + s2.codePointAt(j - 1));
17+
}
18+
}
19+
}
20+
return dp[m][n];
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Solution:
2+
def minimumDeleteSum(self, s1: str, s2: str) -> int:
3+
m, n = len(s1), len(s2)
4+
dp = [[0] * (n + 1) for _ in range(m + 1)]
5+
for i in range(1, m + 1):
6+
dp[i][0] = dp[i - 1][0] + ord(s1[i - 1])
7+
for j in range(1, n + 1):
8+
dp[0][j] = dp[0][j - 1] + ord(s2[j - 1])
9+
for i in range(1, m + 1):
10+
for j in range(1, n + 1):
11+
if s1[i - 1] == s2[j - 1]:
12+
dp[i][j] = dp[i - 1][j - 1]
13+
else:
14+
dp[i][j] = min(dp[i - 1][j] + ord(s1[i - 1]),
15+
dp[i][j - 1] + ord(s2[j - 1]))
16+
return dp[-1][-1]

solution/1100-1199/1143.Longest Common Subsequence/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363

6464
![](https://cdn.jsdelivr.net/gh/doocs/leetcode@main/solution/1100-1199/1143.Longest%20Common%20Subsequence/images/CodeCogsEqn.gif)
6565

66+
时间复杂度 O(mn)。
67+
6668
<!-- tabs:start -->
6769

6870
### **Python3**

0 commit comments

Comments
 (0)