Given two strings word1
and word2
, return the minimum number of operations required to convert word1
to word2
.
You have the following three 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')
Constraints:
0 <= word1.length, word2.length <= 500
word1
andword2
consist of lowercase English letters.
编辑距离。
题意是给两个字符串word1和word2,请返回将 word1 转换成 word2 所使用的最少操作数。这是动态规划的经典题。创建一个二维的数组 dp[i][j] ,代表 word1 到 i 位置转换成 word2 到 j 位置需要最少步数。要让两个单词相同,分三种情况,
- word1减去一个字母 === word2加上一个字母(这两者是等价的所以是同一种情况)
- word1加上一个字母 === word2减去一个字母(等价)
- word1修改一个字母 === word2修改一个字母(等价)
所以判断DP下一步的值的时候需要判断当前字母是否相同,若相同则不需要做任何转换,DP值来源于上一个位置的DP值,dp[i][j] = dp[i - 1][j - 1];若不相同则需要判断如下三种情况哪一种的开销小,
- dp[i - 1][j] - A的前i - 1个字符和B的前j个字符的子问题
- dp[i][j - 1] - A的前i个字符和B的前j - 1个字符的子问题
- dp[i-1][j-1] - A的前 i - 1个字符和B的前i - 1个字符的子问题
时间O(mn)
空间O(mn)
Java实现
1 class Solution { 2 public int minDistance(String word1, String word2) { 3 int len1 = word1.length(); 4 int len2 = word2.length(); 5 int[][] dp = new int[len1 + 1][len2 + 1]; 6 for (int i = 0; i <= len1; i++) { 7 dp[i][0] = i; 8 } 9 for (int j = 0; j <= len2; j++) { 10 dp[0][j] = j; 11 } 12 for (int i = 1; i <= len1; i++) { 13 for (int j = 1; j <= len2; j++) { 14 if (word1.charAt(i - 1) == word2.charAt(j - 1)) { 15 dp[i][j] = dp[i - 1][j - 1]; 16 } else { 17 dp[i][j] = 1 + Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]); 18 } 19 } 20 } 21 return dp[len1][len2]; 22 } 23 }
JavaScript实现
1 /** 2 * @param {string} word1 3 * @param {string} word2 4 * @return {number} 5 */ 6 var minDistance = function(word1, word2) { 7 let len1 = word1.length; 8 let len2 = word2.length; 9 let dp = Array(word1.length + 1) 10 .fill(null) 11 .map(() => Array(word2.length + 1).fill(0)); 12 for (let i = 0; i <= len1; i++) { 13 dp[i][0] = i; 14 } 15 for (let j = 0; j <= len2; j++) { 16 dp[0][j] = j; 17 } 18 for (let i = 1; i <= len1; i++) { 19 for (let j = 1; j <= len2; j++) { 20 if (word1.charAt(i - 1) == word2.charAt(j - 1)) { 21 dp[i][j] = dp[i - 1][j - 1]; 22 } else { 23 dp[i][j] = 24 1 + 25 Math.min( 26 Math.min(dp[i - 1][j], dp[i][j - 1]), 27 dp[i - 1][j - 1] 28 ); 29 } 30 } 31 } 32 return dp[i][j]; 33 };
相关题目