LeetCode第72题(编辑距离)

原题如下:

给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
插入一个字符
删除一个字符
替换一个字符
示例 1:

输入: word1 = “horse”, word2 = “ros”
输出: 3
解释:
horse -> rorse (将 ‘h’ 替换为 ‘r’)
rorse -> rose (删除 ‘r’)
rose -> ros (删除 ‘e’)

这题其实很像LeetCode第44题通配符匹配

需要借助二维数组来记录 字串的(子串的最小操作数)
最开始的想法是把Word1给剪切成 类似于word2的形态,但也仅仅是想想,实际上是很蠢的办法!!!因为当word2中有相同的字符的时候 你不知道 word1里面的那个字符对应于Word2的哪一个?(依次试一试?代价太大!)

关键是下面的想法,拿上面的Word1=“horse” Word2=“ros” 举例说明:
1.在你思考的过程中需要想一想, 如果 Word2=“ro” 的话 我也应该可以求出 最小操作数 是r 也一定!!可以
2.我能不能 用求子串的 最小操作数 来求 比它稍微大一点的串 的操作数?
3.如果能的话,有怎样的关系(能的话,我肯定要用一种数据结构去记录子串的 最小操作数 来计算后面的操作数 ,那么我们用那种数据结构 一个int变量?一维数组?二维数组?)
4.如果我用一种数据结构去记录子串操作数(记录那个子串?或者是哪些子串?)比如:
(1)理论上 我们可以 dp【i】 (i ,from 0 to Word1.size()-1)去记录
Word1的(0—i)变成Word 2 需要的最小操作数
(2)或者 dp【j】(j,from 0 to word2.size()-1) 去记录 word1 (整体的串)变成 word2【j】(0—j)需要的最小操作数
(3)再或者 dp【i】【j】{i表示Word1的(0—-i) j表示Word2的(0——j)}从word1 子串 到 word2子串的 最小操作数
哪种可以推倒出大范围的子串 需要自己仔细思考!!!这里给出以(3)的代码

注意 m【i】【j】的初始化 以及 m【i】【j】是如何从 之前的数据算得的!!!
(ps:min()函数没有写进来)

    void chushihua(vector<vector<int>>&m, string &word1, string &word2){
        int i = 0; int j = 0;
        for (; i <= word1.size() - 1; i++){
            if (word1[i] == word2[0]) break;
        }
        if (i >= word1.size()) {  for (int k = 0; k <= word1.size() - 1; k++) m[k][0] = k + 1; }
        else{
            for (int k = 0; k <=i-1; k++) m[k][0] = k + 1;
            for (int k = i; k <= word1.size() - 1; k++)  m[k][0] = k; 
        }
        for (; j <= word2.size() - 1; j++){
            if (word1[0] == word2[j])break;
        }
        if (j >= word2.size()){ for (int k = 0; k <= word2.size() - 1; k++)m[0][k] = k + 1; }
        else{
            for (int k = 0; k <= j - 1; k++)m[0][k] = k + 1;
            for (int k = j; k <= word2.size() - 1; k++)m[0][k] = k;
        }

    }
    int minDistance(string word1, string word2) {
        if (word2.size() == 0){
            if (word1.size() == 0) return 0;
            else return word1.size();
        }
        if (word1.size() == 0) return word2.size();
        vector<vector<int>>m(word1.size());
        for (int i = 0; i <= m.size() - 1; i++) m[i].resize(word2.size());
        chushihua(m, word1, word2);
        for (int i = 1; i <= m.size() - 1; i++){
            for (int j = 1; j <= m[i].size() - 1; j++){
                if (word1[i] == word2[j]) m[i][j] = m[i - 1][j - 1];
                else{
                    int x = m[i - 1][j - 1] + 1;
                    int y = m[i-1][j] + 1;
                    int z = m[i][j - 1] + 1;
                    x = min(x, y);
                    m[i][j] = min(x, z);
                }
            }
        }
        return m[word1.size() - 1][word2.size() - 1];
    }

猜你喜欢

转载自blog.csdn.net/qq_42203013/article/details/82634550
今日推荐