描述
Given two words word1 and word2, find the minimum number of operations required to convert word1 to word2.
You have the following 3 operations permitted on a word:
- Insert a character
- Delete a character
- Replace a character
Example 1:
Input: word1 = "horse", word2 = "ros"
Output: 3
Explanation:
horse -> rorse (replace 'h' with 'r')
rorse -> rose (remove 'r')
rose -> ros (remove 'e')複製程式碼
Example 2:
Input: word1 = "intention", word2 = "execution"
Output: 5
Explanation:
intention -> inention (remove 't')
inention -> enention (replace 'i' with 'e')
enention -> exention (replace 'n' with 'x')
exention -> exection (replace 'n' with 'c')
exection -> execution (insert 'u')複製程式碼
思路
在動態規劃 01揹包問題中,其中的知乎專欄詳細的講解了這個問題。(但是我看到這個專欄的時候已經考完試了,故考試時未能答出:),似乎帶點難度的題我都沒能答出來)
大部分情況下,dp[i] [j]
和 dp[i-1] [j]
、dp[i] [j-1]
、dp[i-1] [j-1]
肯定存在某種關係。
當字串 word1 的長度為 i
,字串 word2 的長度為 j
時,將 word1 轉化為 word2 所使用的最少操作次數為 dp[i] [j]
,即使用i
、j
來代表兩個字串的狀態。
有時候,陣列的含義並不容易找,還得看自己去領悟。
- 如果我們
word1[i]
與word2 [j]
相等,這個時候不需要進行任何操作,顯然有dp[i] [j] = dp[i-1] [j-1]
,即最短編輯距離不變。 - 如果我們
word1[i]
與word2 [j]
不相等,這個時候我們就必須進行調整,而調整的操作有 3 種,我們要選擇一種。三種操作對應的關係試如下(最短編輯距離都要+1):
- 如果把字元
word1[i]
替換成與word2[j]
相等,則有dp[i] [j] = dp[i-1] [j-1] + 1
,即在兩個字串分別為i、j的基礎上; - 如果在字串 word1末尾插入一個與
word2[j]
相等的字元,則有dp[i] [j] = dp[i] [j-1] + 1
; - 如果把字元
word1[i]
刪除,則有dp[i] [j] = dp[i-1] [j] + 1
;
關係式為dp[i] [j] = min(dp[i-1] [j-1],dp[i] [j-1],dp[[i-1] [j]]) + 1;
class Solution {
public int minDistance(String word1, String word2) {
int s1Len = word1.length(), s2Len = word2.length();
int dp[][] = new int[s1Len+1][s2Len+1];
//對邊界值進行計算
//即邊界值只能通過上一個邊界值+1得來,
//因為一個字串長度為0時,和另一個字串的最短編輯距離差只有增加一種情況。
dp[0][0] = 0;
for(int i = 1; i<s1Len+1; i++){
dp[i][0] = dp[i-1][0] + 1;
}
for(int i = 1; i<s2Len+1; i++){
dp[0][i] = dp[0][i-1] + 1;
}
//填表過程
for(int i = 1; i<s1Len+1; i++){
for(int j = 1; j<s2Len+1; j++){
if(word1.charAt(i-1) == word2.charAt(j-1)){
dp[i][j] = dp[i-1][j-1];
}else{
dp[i][j] = Math.min(Math.min(dp[i-1][j-1], dp[i-1][j]), dp[i][j-1])+1;
}
}
}
return dp[s1Len][s2Len];
}
}複製程式碼
Runtime: 5 ms, faster than 84.06% of Java online submissions for Edit Distance.
Memory Usage: 42 MB, less than 5.88% of Java online submissions for Edit Distance.
找到陣列的含義對解題至關重要,因為它決定著動態規劃的核心——關係式。