【Leetcode】583.Delete Operation for Two Strings
阿新 • • 發佈:2019-02-03
Delete Operation for Two Strings
Given two words word1 and word2, find the minimum number of steps required to make word1 and word2 the same, where in each step you can delete one character in either string.
Example 1:
Input: "sea", "eat" Output: 2 Explanation: You need one step to make "sea" to "ea" and another step to make "eat" to "ea".
Note:
- The length of given words won’t exceed 500.
- Characters in given words can only be lower-case letters.
解析
題目要求,求出如何能快速的使得word1
與word2
兩個單詞變成一樣的。這題是考察最長公共子序列(LCS
)的應用,求出LCS
,然後使用
word1.length+word2.length-2lcs
即可求得結果。
兩種解題思路,第一種是比較熟悉的動態規劃:
建立狀態轉移方程,dp[i][j]
,用來記錄word1
中【0,i】
與word2
中索引[0,j]
中的LCS
,
- 當
word1[i-1]==word2[j-1]
dp[i][j]=dp[i-1][j-1]
- 否則
dp[i][j] = 1 + Math.min(dp[i - 1][j], dp[i][j - 1])
,相當於退而求次,如果i-1
或j-1
位置不相等,那麼我們使得word1,word2
向後退一步,用i
與j-1
或者i-1
與j
來比較。
第二種,使用記憶化+遞迴
建立一個遞迴函式來求解LCS
,一個二維陣列來存放[m,n]
位置的LCS
長度,為了避免重複遞迴計算,我們可以將之前算得的LCS
返回。
程式碼
記憶化+遞迴
public static int minDistance(String word1, String word2) {
int mem[][] = new int[word1.length()+1][word2.length()+1];
return word1.length() + word2.length() - 2 * lcs(word1, word2, word1.length(), word2.length(), mem);
}
private static int lcs(String s1, String s2, int m, int n, int[][] mem) {
if (m == 0 || n == 0) {
return 0;
}
if (mem[m][n] > 0) {
return mem[m][n];
}
if (s1.charAt(m - 1) == s2.charAt(n - 1)) {
mem[m][n] = 1 + lcs(s1, s2, m - 1, n - 1, mem);
} else {
mem[m][n] = Math.max(lcs(s1, s2, m, n - 1, mem), lcs(s1, s2, m - 1, n, mem));
}
return mem[m][n];
}
動態規劃
public static 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 (i == 0 || j == 0)
continue;
if (word1.charAt(i - 1) == word2.charAt(j - 1))
dp[i][j] = 1 + dp[i - 1][j - 1];
else
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
return word1.length() + word2.length() - 2 * dp[word1.length()][word2.length()];
}