/** * @param {string} word1 * @param {string} word2 * @return {number} */ const minDistance = function (word1, word2) { }; /* 有删除,添加,修改三种操作,word1的删除和word2的添加效果是一样的,所以实际上只有三种操作 1. 往word1中删除一个字符 2. 往word2中删除一个字符 3. 修改word1中的一个字符 定义dp[i][j]表示word1的前i个字符和word2的前j个字符的最少编辑距离,那么在已知dp[i-1][j-1]和dp[i-1][j],dp[i][j-1]的情况下推出来 如果第word1的第i个字符和word2的第j个字符相等,那么最小编辑距离就是dp[i-1][j-1]因为第i个数和第j个字符我不需要操作,而剩下的这些字符 最少编辑距离就是dp[i-1][j-1],如果这word1的第i个字符和word2的第j个字符不相等,我们可以删除word1的第i个字符,然后将word1的前i-1个字符 和word2的前j个字符变得一样所需得编辑距离加上删除word1得第i个字符这一步一共是dp[i-1][j] + 1个编辑距离,同理:dp[i][j-1]得原理一样, 最后还有一种获得最优得情况是,我不删除,只是将word1中得最后一个字符修改成和word2中卒子后一个字符一样,这样就变成word1[i-1]==word2[j-1] 相等得情况了。 */ function f1(word1, word2) { const m = word1.length; const n = word2.length; const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0)); // 初始化成0无意义,只是初始化而已 // 初始化,如果word1为空,word2要想变得和word1一样,编辑距离就是它自身长度 for (let j = 0; j <= n; j++) { dp[0][j] = j; } // word2为空同理 for (let i = 0; i <= m; i++) { dp[i][0] = i; } // 填dp表,dp[i][j] 依赖dp[i-1][j-1], dp[i-1][j], dp[i][j-1],所以要从上到下,从左到右遍历 for (let i = 1; i <= m; i++) { for (let j = 1; j <= n; j++) { if (word1[i - 1] === word2[j - 1]) { dp[i][j] = dp[i - 1][j - 1]; } else { dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1; } } } return dp[m][n]; }