LeetCode 72. Edit Distance
原题链接在这里:https://leetcode.com/problems/edit-distance/
题目:
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.)
You have the following 3 operations permitted on a word:
a) Insert a character
b) Delete a character
c) Replace a character
题解:
要求word1 convert成word2 需要的最少operations. 需要储存历史信息是word1到i段 convert成 word2 到j段需要的最少operations数目.
Let dp[i][j] denotes the minimum number of operations to convert from word1 till index i to word2 till index j.
递推时,有两种情况,一种是word1 和 word2新检查的字符相同,那么operations数目dp[i][j]就没有变,还是dp[i-1][j-1].
若是字符不同的话就有三种操作:
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.