思路:本題要求使得 word1 和 word2 相同所需要?jiǎng)h除的最小字符數(shù),也就是說(shuō)要找到最大的公共子串需要?jiǎng)h除多少個(gè)字符,那么本題依舊可以延續(xù)之前的思路,不同的地方在于本題是兩個(gè)字符串都可以刪,也就是在推導(dǎo)條件的時(shí)候需要做出變化,其他基本思路相同。
我們?cè)O(shè) dp[i][j]表示以word1[i-1]結(jié)尾字符串和word2[j-1]結(jié)尾的字符串想要達(dá)到相等要?jiǎng)h去的次數(shù)。那么我們需要初始化所有的dp[i][0]和dp[0][j],以word1[i-1]結(jié)尾字符串和字
符串0想要達(dá)到相等要?jiǎng)h去的次數(shù)很明顯為字符串長(zhǎng)度本身,所以初始化如下:
for (int i = 0; i < word1.length() + 1;i++){
dp[i][0] = i;
}
for (int j = 0; j < word2.length() + 1;j++){
dp[0][j] = j;
}
在遍歷中我們同樣以word1.charAt(i-1) == word2.charAt(j-1),作為判斷條件來(lái)進(jìn)行dp數(shù)組的推導(dǎo),當(dāng)相等的時(shí)候,我們沒(méi)必要進(jìn)行刪除,直接繼承兩個(gè)字符串上一位的dp值即可。當(dāng)不相等的時(shí)候,我們需要進(jìn)行刪除,這里考慮的情況就比較多,我們可以刪去任意一個(gè)字符串的字符,dp[i-1][j]+1或者dp[i][j-1]+1,或者兩個(gè)字符串都進(jìn)行刪除dp[i-1][j-1]+2,從中選一個(gè)最小的即可
class Solution {
public int minDistance(String word1, String word2) {
// dp[i][j]表示以word1[i-1]結(jié)尾字符串和word2[j-1]結(jié)尾的字符串想要達(dá)到相等要?jiǎng)h去的次數(shù)
int[][] dp = new int[word1.length() + 1][word2.length() + 1];
for (int i = 0; i < word1.length() + 1;i++){
dp[i][0] = i;
}
for (int j = 0; j < word2.length() + 1;j++){
dp[0][j] = j;
}
for (int i = 1; i < word1.length()+1; i++) {
for (int j = 1; j < word2.length() + 1 ; j++) {
if (word1.charAt(i-1) == word2.charAt(j-1)){
// 不用刪直接繼承兩邊上一位的dp即可
dp[i][j] = dp[i-1][j-1];
}else {
// 兩邊都可以刪,或者只刪一邊(只是在邏輯上刪去)
dp[i][j] = Math.min(dp[i-1][j]+1,Math.min(dp[i][j-1]+1,dp[i-1][j-1]+2));
}
}
}
return dp[word1.length()][word2.length()];
}
}