Skip to content

Commit d98a926

Browse files
authored
feat: add solutions to lc problem: No.0583 (doocs#3968)
No.0583.Delete Operation for Two Strings
1 parent 9979b19 commit d98a926

File tree

8 files changed

+258
-166
lines changed

8 files changed

+258
-166
lines changed

solution/0500-0599/0583.Delete Operation for Two Strings/README.md

+86-56
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,15 @@ tags:
5656

5757
### 方法一:动态规划
5858

59-
类似[1143. 最长公共子序列](https://github.com/doocs/leetcode/blob/main/solution/1100-1199/1143.Longest%20Common%20Subsequence/README.md)
59+
我们定义 $f[i][j]$ 表示使得字符串 $\textit{word1}$ 的前 $i$ 个字符和字符串 $\textit{word2}$ 的前 $j$ 个字符相同的最小删除步数。那么答案为 $f[m][n]$,其中 $m$ 和 $n$ 分别是字符串 $\textit{word1}$ 和 $\textit{word2}$ 的长度
6060

61-
定义 `dp[i][j]` 表示使得 `word1[0:i-1]``word1[0:j-1]` 两个字符串相同所需执行的删除操作次数
61+
初始时,如果 $j = 0$,那么 $f[i][0] = i$;如果 $i = 0$,那么 $f[0][j] = j$
6262

63-
时间复杂度:$O(mn)$。
63+
当 $i, j > 0$ 时,如果 $\textit{word1}[i - 1] = \textit{word2}[j - 1]$,那么 $f[i][j] = f[i - 1][j - 1]$;否则 $f[i][j] = \min(f[i - 1][j], f[i][j - 1]) + 1$。
64+
65+
最终返回 $f[m][n]$ 即可。
66+
67+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是字符串 $\textit{word1}$ 和 $\textit{word2}$ 的长度。
6468

6569
<!-- tabs:start -->
6670

@@ -70,18 +74,18 @@ tags:
7074
class Solution:
7175
def minDistance(self, word1: str, word2: str) -> int:
7276
m, n = len(word1), len(word2)
73-
dp = [[0] * (n + 1) for _ in range(m + 1)]
77+
f = [[0] * (n + 1) for _ in range(m + 1)]
7478
for i in range(1, m + 1):
75-
dp[i][0] = i
79+
f[i][0] = i
7680
for j in range(1, n + 1):
77-
dp[0][j] = j
78-
for i in range(1, m + 1):
79-
for j in range(1, n + 1):
80-
if word1[i - 1] == word2[j - 1]:
81-
dp[i][j] = dp[i - 1][j - 1]
81+
f[0][j] = j
82+
for i, a in enumerate(word1, 1):
83+
for j, b in enumerate(word2, 1):
84+
if a == b:
85+
f[i][j] = f[i - 1][j - 1]
8286
else:
83-
dp[i][j] = 1 + min(dp[i - 1][j], dp[i][j - 1])
84-
return dp[-1][-1]
87+
f[i][j] = min(f[i - 1][j], f[i][j - 1]) + 1
88+
return f[m][n]
8589
```
8690

8791
#### Java
@@ -90,23 +94,25 @@ class Solution:
9094
class Solution {
9195
public int minDistance(String word1, String word2) {
9296
int m = word1.length(), n = word2.length();
93-
int[][] dp = new int[m + 1][n + 1];
94-
for (int i = 1; i <= m; ++i) {
95-
dp[i][0] = i;
97+
int[][] f = new int[m + 1][n + 1];
98+
for (int i = 0; i <= m; ++i) {
99+
f[i][0] = i;
96100
}
97-
for (int j = 1; j <= n; ++j) {
98-
dp[0][j] = j;
101+
for (int j = 0; j <= n; ++j) {
102+
f[0][j] = j;
99103
}
100104
for (int i = 1; i <= m; ++i) {
101105
for (int j = 1; j <= n; ++j) {
102-
if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
103-
dp[i][j] = dp[i - 1][j - 1];
106+
char a = word1.charAt(i - 1);
107+
char b = word2.charAt(j - 1);
108+
if (a == b) {
109+
f[i][j] = f[i - 1][j - 1];
104110
} else {
105-
dp[i][j] = 1 + Math.min(dp[i - 1][j], dp[i][j - 1]);
111+
f[i][j] = Math.min(f[i - 1][j], f[i][j - 1]) + 1;
106112
}
107113
}
108114
}
109-
return dp[m][n];
115+
return f[m][n];
110116
}
111117
}
112118
```
@@ -117,19 +123,26 @@ class Solution {
117123
class Solution {
118124
public:
119125
int minDistance(string word1, string word2) {
120-
int m = word1.size(), n = word2.size();
121-
vector<vector<int>> dp(m + 1, vector<int>(n + 1));
122-
for (int i = 1; i <= m; ++i) dp[i][0] = i;
123-
for (int j = 1; j <= n; ++j) dp[0][j] = j;
126+
int m = word1.length(), n = word2.length();
127+
vector<vector<int>> f(m + 1, vector<int>(n + 1));
128+
for (int i = 0; i <= m; ++i) {
129+
f[i][0] = i;
130+
}
131+
for (int j = 0; j <= n; ++j) {
132+
f[0][j] = j;
133+
}
124134
for (int i = 1; i <= m; ++i) {
125135
for (int j = 1; j <= n; ++j) {
126-
if (word1[i - 1] == word2[j - 1])
127-
dp[i][j] = dp[i - 1][j - 1];
128-
else
129-
dp[i][j] = 1 + min(dp[i - 1][j], dp[i][j - 1]);
136+
char a = word1[i - 1];
137+
char b = word2[j - 1];
138+
if (a == b) {
139+
f[i][j] = f[i - 1][j - 1];
140+
} else {
141+
f[i][j] = min(f[i - 1][j], f[i][j - 1]) + 1;
142+
}
130143
}
131144
}
132-
return dp[m][n];
145+
return f[m][n];
133146
}
134147
};
135148
```
@@ -139,24 +152,25 @@ public:
139152
```go
140153
func minDistance(word1 string, word2 string) int {
141154
m, n := len(word1), len(word2)
142-
dp := make([][]int, m+1)
143-
for i := range dp {
144-
dp[i] = make([]int, n+1)
145-
dp[i][0] = i
155+
f := make([][]int, m+1)
156+
for i := range f {
157+
f[i] = make([]int, n+1)
158+
f[i][0] = i
146159
}
147-
for j := range dp[0] {
148-
dp[0][j] = j
160+
for j := 1; j <= n; j++ {
161+
f[0][j] = j
149162
}
150163
for i := 1; i <= m; i++ {
151164
for j := 1; j <= n; j++ {
152-
if word1[i-1] == word2[j-1] {
153-
dp[i][j] = dp[i-1][j-1]
165+
a, b := word1[i-1], word2[j-1]
166+
if a == b {
167+
f[i][j] = f[i-1][j-1]
154168
} else {
155-
dp[i][j] = 1 + min(dp[i-1][j], dp[i][j-1])
169+
f[i][j] = 1 + min(f[i-1][j], f[i][j-1])
156170
}
157171
}
158172
}
159-
return dp[m][n]
173+
return f[m][n]
160174
}
161175
```
162176

@@ -166,18 +180,23 @@ func minDistance(word1 string, word2 string) int {
166180
function minDistance(word1: string, word2: string): number {
167181
const m = word1.length;
168182
const n = word2.length;
169-
const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
170-
for (let i = 1; i <= m; i++) {
171-
for (let j = 1; j <= n; j++) {
183+
const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
184+
for (let i = 1; i <= m; ++i) {
185+
f[i][0] = i;
186+
}
187+
for (let j = 1; j <= n; ++j) {
188+
f[0][j] = j;
189+
}
190+
for (let i = 1; i <= m; ++i) {
191+
for (let j = 1; j <= n; ++j) {
172192
if (word1[i - 1] === word2[j - 1]) {
173-
dp[i][j] = dp[i - 1][j - 1] + 1;
193+
f[i][j] = f[i - 1][j - 1];
174194
} else {
175-
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
195+
f[i][j] = Math.min(f[i - 1][j], f[i][j - 1]) + 1;
176196
}
177197
}
178198
}
179-
const max = dp[m][n];
180-
return m - max + n - max;
199+
return f[m][n];
181200
}
182201
```
183202

@@ -186,20 +205,31 @@ function minDistance(word1: string, word2: string): number {
186205
```rust
187206
impl Solution {
188207
pub fn min_distance(word1: String, word2: String) -> i32 {
189-
let (m, n) = (word1.len(), word2.len());
190-
let (word1, word2) = (word1.as_bytes(), word2.as_bytes());
191-
let mut dp = vec![vec![0; n + 1]; m + 1];
208+
let m = word1.len();
209+
let n = word2.len();
210+
let s: Vec<char> = word1.chars().collect();
211+
let t: Vec<char> = word2.chars().collect();
212+
let mut f = vec![vec![0; n + 1]; m + 1];
213+
214+
for i in 0..=m {
215+
f[i][0] = i as i32;
216+
}
217+
for j in 0..=n {
218+
f[0][j] = j as i32;
219+
}
220+
192221
for i in 1..=m {
193222
for j in 1..=n {
194-
dp[i][j] = if word1[i - 1] == word2[j - 1] {
195-
dp[i - 1][j - 1] + 1
223+
let a = s[i - 1];
224+
let b = t[j - 1];
225+
if a == b {
226+
f[i][j] = f[i - 1][j - 1];
196227
} else {
197-
dp[i - 1][j].max(dp[i][j - 1])
198-
};
228+
f[i][j] = std::cmp::min(f[i - 1][j], f[i][j - 1]) + 1;
229+
}
199230
}
200231
}
201-
let max = dp[m][n];
202-
(m - max + (n - max)) as i32
232+
f[m][n]
203233
}
204234
}
205235
```

0 commit comments

Comments
 (0)