119.编辑距离(JavaScript)

用JavaScript比较多,错误之处请指出

 

题目

119. 编辑距离
给出两个单词word1和word2,计算出将word1 转换为word2的最少操作次数。

你总共三种操作方法:

插入一个字符
删除一个字符
替换一个字符
样例
给出 work1="mart" 和 work2="karma"

返回 3

  

思路

这里主要运用动态规划算法来解决问题

动态规划算法:动态规划算法的基本思想与分治法类似,也是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,最后一个子问题就是初始问题的解。

可以看出动态规划一大特点是从前一个阶段转化到后一个阶段之间的递推关系,那么我们可以建立一个二维表格arr[i][j] 表示word1的前i项转换成word2前j项的所花费的最短步数(i,j分别代表字符串word1和字符串word2的长度),我们只要通过循环,把每一个阶段的步数作为值逐渐添加到二维表格里面就可以了。

那么循环的情况共有

1.i 或者j 为0 

这种很好理解,谁为0则花费步数就为另一个的长度。如i=0 arr[i][j] = j

 

2.word1[i-1] == word2 [j-1]

这种情况意思是字符串最后一项字符相等,那么根据二维表格,只要考虑到转换前一项的步数就可以了,即arr[i][j] = arr[i-1][j-1]

 

3.word1[i-1] != word2 [j-1]

因为我们需要知道word1的第i项转换成word2的第j项(即arr[i][j])所需要步数,那么这里可能需要添加,删除,或者变换,我们只要找出最短的步数就可以的。

添加:

想通过添加操作求得arr[i][j],意思是word1的前i-1项等于word2的前j项了,做一个添加操作就可以得到arr[i][j],那么arr[i][j] = arr[i][j-1]+1

删除:

想通过删除操作求得arr[i][j],意思是word1的前i项已经等于word2的前j项了,word1做一个删除操作就可以得到arr[i][j],那么arr[i][j] = arr[i-1][j]+1

替换:

通过替换操作求得arr[i][j],意思是word1的前i-1项已经等于word2的前j-1项了,word1的第i项替换一个字符,即做一个替换操作就可以得到arr[i][j],那么arr[i][j] = arr[i-1][j-1]+1

代码

 

/**
 * @param word1: A string
 * @param word2: A string
 * @return: The minimum number of steps.
 */
const minDistance = function (word1, word2) {
    //先转换成数组格式
    var arr1 = word1.split("");
    var arr2 = word2.split("");
    //计算长度
    var len1 = arr1.length;
    var len2 = arr2.length;
    //创建一个二维数组
    var arr =  new Array(len1 + 1);   //表格有len1 + 1行
    for(var k = 0;k < arr.length; k++){
       arr[k] = new Array(len2 + 1);    //每行有len2 +1列
    }
    for (var i = 0; i <= len1; i++) {
        for (var j = 0; j <= len2; j++) {
            if (i == 0) {
                //i=0 的情况,表示需要插入j个字符
                arr[i][j] = j;   
            }else if (j == 0 ) {
                //j=0的情况,表示需要删除i个字符
                arr[i][j] = i;    
            }else if (arr1[i-1] == arr2[j-1]) {   
                //表示word1第i项和word2第j项最后的一个字符相同的情况,只要考虑到两者的前一步,也就是arr1[i-1][j-1]的情况就可以了
                arr[i][j] = arr[i-1][j-1];
            }else {                         
                //从插入,删除,删除中选择最小的步数加1即可 
                arr[i][j] = Math.min(arr[i-1][j],arr[i][j-1],arr[i-1][j-1])+1;
            }
        }
    }
    //返回最小的操作步数
    return arr[len1][len2]
}

 

posted @ 2018-07-26 00:28  chobyn  阅读(174)  评论(0)    收藏  举报