Skip to content

Commit 9db4eaa

Browse files
committed
0583-delete-operation-for-two-strings.md Supported 7 languages.
1 parent b739a22 commit 9db4eaa

File tree

1 file changed

+235
-0
lines changed

1 file changed

+235
-0
lines changed
+235
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
# 583. Delete Operation for Two Strings
2+
LeetCode problem: [583. Delete Operation for Two Strings](https://leetcode.com/problems/delete-operation-for-two-strings/)
3+
4+
## Problem
5+
> Given two strings `word1` and `word2`, return the **minimum** number of **steps** required to make `word1` and `word2` the same.
6+
7+
In one step, you can delete exactly one character in either string.
8+
9+
```
10+
Example 1:
11+
Input: word1 = "sea", word2 = "eat"
12+
Output: 2
13+
Explanation: You need one step to make "sea" to "ea" and another step to make "eat" to "ea".
14+
15+
Example 2:
16+
Input: word1 = "leetcode", word2 = "etco"
17+
Output: 4
18+
```
19+
20+
## Thoughts
21+
* It is a question of comparing two strings. After doing similar questions many times, we will develop an intuition to use dynamic programming with two-dimensional arrays.
22+
23+
### Common steps in dynamic programming
24+
These five steps are a pattern for solving dynamic programming problems.
25+
26+
1. Determine the **meaning** of the `dp[i][j]`
27+
* Since there are two strings, we can use two-dimensional arrays as the default option.
28+
* At first, try to use the problem's `return` value as the value of `dp[i][j]` to determine the meaning of `dp[i][j]`. If it doesn't work, try another way.
29+
* `dp[i][j]` represents the **minimum** number of steps required to make `word1`'s first `i` letters and `word2`'s first `j` letters the same.
30+
* The value of `dp[i][j]` is an integer.
31+
2. Determine the `dp` array's recurrence formula
32+
* Use an example:
33+
```
34+
After initialized, the 'dp' array would be:
35+
# e a t
36+
# 0 1 2 3 # dp[0] is for empty string, the number of steps is just the number of chars to be deleted
37+
# s 1 0 0 0
38+
# e 2 0 0 0
39+
# a 3 0 0 0
40+
```
41+
42+
```
43+
The final 'dp' array would be:
44+
# e a t
45+
# 0 1 2 3
46+
# s 1 2 3 4
47+
# e 2 1 2 3
48+
# a 3 2 1 2
49+
```
50+
* Recurrence formula:
51+
```python
52+
if word1[i - 1] == word2[j - 1]
53+
dp[i][j] = dp[i - 1][j - 1]
54+
else
55+
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + 1
56+
```
57+
58+
3. Determine the `dp` array's initial value
59+
* `dp[0][j] = j`, because `dp[0]` represents the empty string, and the number of steps is just the number of chars to be deleted
60+
* `dp[i][0] = i`, the reason is the same as previous line, yet in vertical direction.
61+
4. Determine the `dp` array's traversal order
62+
* `dp[i][j]` depends on `dp[i - 1][j - 1]`, `dp[i - 1][j]` and `dp[i][j - 1]`, so we should traverse the `dp` array from top to bottom, then from left to right.
63+
5. Check the `dp` array's value
64+
* Print the `dp` to see if it is as expected.
65+
66+
### Complexity
67+
* Time: `O(n * m)`.
68+
* Space: `O(n * m)`.
69+
70+
## Python
71+
```python
72+
class Solution:
73+
def minDistance(self, word1: str, word2: str) -> int:
74+
dp = [[0] * (len(word2) + 1) for _ in range(len(word1) + 1)]
75+
for i in range(len(dp)):
76+
dp[i][0] = i
77+
for j in range(len(dp[0])):
78+
dp[0][j] = j
79+
80+
for i in range(1, len(dp)):
81+
for j in range(1, len(dp[0])):
82+
if word1[i - 1] == word2[j - 1]:
83+
dp[i][j] = dp[i - 1][j - 1]
84+
else:
85+
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + 1
86+
87+
return dp[-1][-1]
88+
```
89+
90+
## C++
91+
```cpp
92+
class Solution {
93+
public:
94+
int minDistance(string word1, string word2) {
95+
vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1));
96+
for (int i = 0; i < dp.size(); i++)
97+
dp[i][0] = i;
98+
for (int j = 0; j < dp[0].size(); j++)
99+
dp[0][j] = j;
100+
101+
for (int i = 1; i < dp.size(); i++) {
102+
for (int j = 1; j < dp[0].size(); j++) {
103+
if (word1[i - 1] == word2[j - 1])
104+
dp[i][j] = dp[i - 1][j - 1];
105+
else
106+
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + 1;
107+
}
108+
}
109+
110+
return dp[dp.size() - 1][dp[0].size() - 1];
111+
}
112+
};
113+
```
114+
115+
## Java
116+
```java
117+
class Solution {
118+
public int minDistance(String word1, String word2) {
119+
var dp = new int[word1.length() + 1][word2.length() + 1];
120+
for (int i = 0; i < dp.length; i++)
121+
dp[i][0] = i;
122+
for (int j = 0; j < dp[0].length; j++)
123+
dp[0][j] = j;
124+
125+
for (int i = 1; i < dp.length; i++) {
126+
for (int j = 1; j < dp[0].length; j++) {
127+
if (word1.charAt(i - 1) == word2.charAt(j - 1))
128+
dp[i][j] = dp[i - 1][j - 1];
129+
else
130+
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + 1;
131+
}
132+
}
133+
134+
return dp[dp.length - 1][dp[0].length - 1];
135+
}
136+
}
137+
```
138+
139+
## C#
140+
```c#
141+
public class Solution {
142+
public int MinDistance(string word1, string word2) {
143+
var dp = new int[word1.Length + 1][];
144+
for (int i = 0; i < dp.Length; i++) {
145+
dp[i] = new int[word2.Length + 1];
146+
dp[i][0] = i;
147+
}
148+
for (int j = 0; j < dp[0].Length; j++)
149+
dp[0][j] = j;
150+
151+
for (int i = 1; i < dp.Length; i++) {
152+
for (int j = 1; j < dp[0].Length; j++) {
153+
if (word1[i - 1] == word2[j - 1])
154+
dp[i][j] = dp[i - 1][j - 1];
155+
else
156+
dp[i][j] = Math.Min(dp[i - 1][j], dp[i][j - 1]) + 1;
157+
}
158+
}
159+
160+
return dp[dp.Length - 1][dp[0].Length - 1];
161+
}
162+
}
163+
```
164+
165+
## JavaScript
166+
```javascript
167+
var minDistance = function(word1, word2) {
168+
let dp = Array(word1.length + 1).fill().map(
169+
() => Array(word2.length + 1).fill(0)
170+
)
171+
dp.forEach((_, i) => { dp[i][0] = i })
172+
dp[0].forEach((_, j) => { dp[0][j] = j })
173+
174+
for (let i = 1; i < dp.length; i++) {
175+
for (let j = 1; j < dp[0].length; j++) {
176+
if (word1[i - 1] == word2[j - 1])
177+
dp[i][j] = dp[i - 1][j - 1]
178+
else
179+
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + 1
180+
}
181+
}
182+
183+
return dp.at(-1).at(-1)
184+
};
185+
```
186+
187+
## Go
188+
```go
189+
func minDistance(word1 string, word2 string) int {
190+
dp := make([][]int, len(word1) + 1)
191+
for i := range dp {
192+
dp[i] = make([]int, len(word2) + 1)
193+
dp[i][0] = i
194+
}
195+
for j := range dp[0] {
196+
dp[0][j] = j
197+
}
198+
199+
for i := 1; i < len(dp); i++ {
200+
for j := 1; j < len(dp[0]); j++ {
201+
if word1[i - 1] == word2[j - 1] {
202+
dp[i][j] = dp[i - 1][j - 1]
203+
} else {
204+
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + 1
205+
}
206+
}
207+
}
208+
209+
return dp[len(dp) - 1][len(dp[0]) - 1]
210+
}
211+
```
212+
213+
## Ruby
214+
```ruby
215+
def min_distance(word1, word2)
216+
dp = Array.new(word1.size + 1) do |i|
217+
Array.new(word2.size + 1, 0)
218+
end
219+
dp.each_with_index { |_, i| dp[i][0] = i }
220+
dp[0].each_with_index { |_, j| dp[0][j] = j }
221+
222+
for i in 1..dp.size - 1
223+
for j in 1..dp[0].size - 1
224+
dp[i][j] =
225+
if word1[i - 1] == word2[j - 1]
226+
dp[i - 1][j - 1]
227+
else
228+
[dp[i - 1][j], dp[i][j - 1]].min + 1
229+
end
230+
end
231+
end
232+
233+
dp[-1][-1]
234+
end
235+
```

0 commit comments

Comments
 (0)