@@ -56,11 +56,15 @@ tags:
56
56
57
57
### 方法一:动态规划
58
58
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}$ 的长度 。
60
60
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$ 。
62
62
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}$ 的长度。
64
68
65
69
<!-- tabs:start -->
66
70
@@ -70,18 +74,18 @@ tags:
70
74
class Solution :
71
75
def minDistance (self , word1 : str , word2 : str ) -> int :
72
76
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 )]
74
78
for i in range (1 , m + 1 ):
75
- dp [i][0 ] = i
79
+ f [i][0 ] = i
76
80
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 ]
82
86
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 ]
85
89
```
86
90
87
91
#### Java
@@ -90,23 +94,25 @@ class Solution:
90
94
class Solution {
91
95
public int minDistance (String word1 , String word2 ) {
92
96
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;
96
100
}
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;
99
103
}
100
104
for (int i = 1 ; i <= m; ++ i) {
101
105
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 ];
104
110
} 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 ;
106
112
}
107
113
}
108
114
}
109
- return dp [m][n];
115
+ return f [m][n];
110
116
}
111
117
}
112
118
```
@@ -117,19 +123,26 @@ class Solution {
117
123
class Solution {
118
124
public:
119
125
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
+ }
124
134
for (int i = 1; i <= m; ++i) {
125
135
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
+ }
130
143
}
131
144
}
132
- return dp [ m] [ n ] ;
145
+ return f [ m] [ n ] ;
133
146
}
134
147
};
135
148
```
@@ -139,24 +152,25 @@ public:
139
152
```go
140
153
func minDistance(word1 string, word2 string) int {
141
154
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
146
159
}
147
- for j := range dp[0] {
148
- dp [0][j] = j
160
+ for j := 1; j <= n; j++ {
161
+ f [0][j] = j
149
162
}
150
163
for i := 1; i <= m; i++ {
151
164
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]
154
168
} 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])
156
170
}
157
171
}
158
172
}
159
- return dp [m][n]
173
+ return f [m][n]
160
174
}
161
175
```
162
176
@@ -166,18 +180,23 @@ func minDistance(word1 string, word2 string) int {
166
180
function minDistance(word1 : string , word2 : string ): number {
167
181
const m = word1 .length ;
168
182
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 ) {
172
192
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 ];
174
194
} 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 ;
176
196
}
177
197
}
178
198
}
179
- const max = dp [m ][n ];
180
- return m - max + n - max ;
199
+ return f [m ][n ];
181
200
}
182
201
```
183
202
@@ -186,20 +205,31 @@ function minDistance(word1: string, word2: string): number {
186
205
``` rust
187
206
impl Solution {
188
207
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
+
192
221
for i in 1 ..= m {
193
222
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 ];
196
227
} 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
+ }
199
230
}
200
231
}
201
- let max = dp [m ][n ];
202
- (m - max + (n - max )) as i32
232
+ f [m ][n ]
203
233
}
204
234
}
205
235
```
0 commit comments