原題連接在這裏:https://leetcode.com/problems/edit-distance/html
題目:post
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)ui
You have the following 3 operations permitted on a word:url
a) Insert a character
b) Delete a character
c) Replace a characterspa
題解:code
要求word1 convert成word2 須要的最少operations. 須要儲存歷史信息是word1到i段 convert成 word2 到j段須要的最少operations數目.htm
Let dp[i][j] denotes the minimum number of operations to convert from word1 till index i to word2 till index j. blog
遞推時,有兩種狀況,一種是word1 和 word2新檢查的字符相同,那麼operations數目dp[i][j]就沒有變,仍是dp[i-1][j-1].leetcode
如果字符不一樣的話就有三種操做:get
1. 向word1插入1字符,operations數目是dp[i-1][j] + 1;
2. 從word1減去1字符,operations數目是dp[i][j-1] +1;(能夠理解成是向word2插入1字符,意思是相通的)
3. word1 replace 1字符, operations數目是dp[i-1][j-1]+1.
dp[i][j]取上面三個數字中最小的.
初始化一個從0 convert 成另外一個到j的位置天然須要j次insert.
答案是dp[len1][len2].
Time Complexity: O(len1 * len2). Space: O(len1 * len2).
AC Java:
1 public class Solution { 2 public int minDistance(String word1, String word2) { 3 if(word1 == null || word2 == null){ 4 return -1; 5 } 6 int len1 = word1.length(); 7 int len2 = word2.length(); 8 int [][] dp = new int[len1+1][len2+1]; 9 for(int i=0; i<=len1; i++){ 10 dp[i][0] = i; 11 } 12 for(int j=0; j<=len2; j++){ 13 dp[0][j] = j; 14 } 15 for(int i=1; i<=len1; i++){ 16 for(int j=1; j<=len2; j++){ 17 if(word1.charAt(i-1) == word2.charAt(j-1)){ 18 dp[i][j] = dp[i-1][j-1]; 19 }else{ 20 int insert = dp[i-1][j] + 1; 21 int delete = dp[i][j-1] + 1; 22 int replace = dp[i-1][j-1] + 1; 23 dp[i][j] = Math.min(insert, Math.min(delete,replace)); 24 } 25 } 26 } 27 return dp[len1][len2]; 28 } 29 }
只用到了dp[i-1][j-1]. dp[i-1][j] 和dp[i][j-1]三個數據. 能夠降維節省空間.
Time Complexity: O(len1*len2). Space: O(len2).
AC Java:
1 class Solution { 2 public int minDistance(String word1, String word2) { 3 if(word1 == null || word2 == null){ 4 throw new IllegalArgumentException("Invalid input strings."); 5 } 6 7 int len1 = word1.length(); 8 int len2 = word2.length(); 9 int [] dp = new int[len2+1]; 10 for(int j = 0; j<=len2; j++){ 11 dp[j] = j; 12 } 13 14 for(int i = 1; i<=len1; i++){ 15 int prev = i; 16 for(int j = 1; j<=len2; j++){ 17 int cur; 18 if(word1.charAt(i-1) == word2.charAt(j-1)){ 19 cur = dp[j-1]; 20 }else{ 21 int insert = dp[j]+1; 22 int delete = prev+1; 23 int replace = dp[j-1]+1; 24 cur = Math.min(insert, Math.min(delete, replace)); 25 } 26 27 dp[j-1] = prev; 28 prev = cur; 29 } 30 dp[len2] = prev; 31 } 32 return dp[len2]; 33 } 34 }
相似One Edit Distance, Delete Operation for Two Strings, Minimum ASCII Delete Sum for Two Strings, Longest Common Subsequence, Regular Expression Matching.