一、题目
给定两个单词 _word1 _和 word2,找到使得 _word1 _和 _word2 _相同所需的最小步数,每步可以删除任意一个字符串中的一个字符。
点击查看原题
难度级别: 中等
二、思路
1)动态规划
该题可以将问题转化为寻找两个字符串中相同的最长字符序列
让dp[i][j]
为word2[0, i-1]
和word2[0, j-1]
相同最长字符序列长度,那么可以得到状态转移方程:
d
p
[
i
]
[
j
]
=
{
d
p
[
i
−
1
]
[
j
−
1
]
+
1
,
w
o
r
d
1
[
i
]
=
=
w
o
r
d
2
[
j
]
m
a
x
(
d
p
[
i
]
[
j
−
1
]
,
d
p
[
i
−
1
]
[
j
]
)
,
e
l
s
e
dp[i][j]=\left\{\begin{matrix} dp[i-1][j-1]+1,word1[i]==word2[j]\\ max(dp[i][j-1],dp[i-1][j]),else \end{matrix}\right.
dp[i][j]={dp[i−1][j−1]+1,word1[i]==word2[j]max(dp[i][j−1],dp[i−1][j]),else
由于状态只依赖于当前行和i-1
行状态,可以优化为一维dp
数组
三、代码
1)动态规划
class Solution {
public int minDistance(String word1, String word2) {
int[][] dp = new int[word1.length() + 1][word2.length() + 1];
for (int i = 0; i < word1.length(); i++) {
for (int j = 0; j < word2.length(); j++) {
if (word1.charAt(i) == word2.charAt(j)) {
dp[i+1][j+1] = dp[i][j] + 1;
} else {
dp[i+1][j+1] = Math.max(dp[i][j+1], dp[i+1][j]);
}
}
}
return word1.length() + word2.length() - 2*dp[word1.length()][word2.length()];
}
}
两个字符串长度分别为n
和m
,时间复杂度为O(n*m)
,空间复杂度为O(n*m)
优化空间复杂度后为:
class Solution {
public int minDistance(String word1, String word2) {
int[] dp = new int[word2.length() + 1];
for (int i = 0; i < word1.length(); i++) {
int cur = 0; // 记录上一个,如果当前是j+1,那也就是dp[j]元素
for (int j = 0; j < word2.length(); j++) {
int leftTop = cur;
cur = dp[j + 1];
if (word1.charAt(i) == word2.charAt(j)) {
dp[j+1] = leftTop + 1;
} else {
dp[j+1] = Math.max(dp[j+1], dp[j]);
}
}
}
return word1.length() + word2.length() - 2*dp[word2.length()];
}
}
两个字符串长度分别为n
和m
,时间复杂度为O(n*m)
,空间复杂度为O(m)