leetcode 编辑距离 困难

leetcode 编辑距离 困难

 

 

①:暴搜,对于 word1[i] 与 word2[j],如果二者不相等,有三种方式,即题目所说的那种方式。

优化1:记忆化,每一次都记住到 i,j 位置时已经使用过的次数,如果某一次搜索时,出现已使用次数大于所记录的次数时,可直接return,因为没有意义。

优化2:假设 word1 为长的串,那么答案永远不可能大于 word1.size() - word2.size() + word2.size(),即,先让两者长度相等,再依次使用替换操作。

②:dp[i][j] 表示 word1 的前 i 个变成 word2 的前 j 个所使用的最少次数。那么:

dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + 1  // 分别对应删操作与增操作

dp[i][j] = min(dp[i][j], dp[i - 1][j - 1] + (word1[i] != word2[j]);  // 替换

唯一需要注意的就是初始化的问题:即当 i == 0 与 j == 0 的情况,即前 0 的 dp 值初始化

// 记忆化搜索
class Solution {
public:
    int minDistance(const string &word1, const string &word2) {
        const string &a = word1.size() < word2.size() ? word2 : word1;
        const string &b = word1.size() < word2.size() ? word1 : word2;
        tag.resize(a.size() + 1, vector<int>(b.size() + 1, 1e9));
        solve(a, b, 0, 0, 0);
        return ret;
    }

private:
    int ret = 1e9;
    vector<vector<int>> tag;
    void solve(const string &word1, const string &word2, int i, int j, int cnt) {
        // 已保证 word1.size() > word2.size()
        // 那么 cnt 的最大值就是: 删除word1直到二者长度相等, 然后再按 word2.size() 逐个替换
        if(cnt > (int)word1.size() - (int)word2.size() + (int)word2.size() || cnt >= ret) return;
        if(i == word1.size() || j == word2.size()) {
            if(j != word2.size()) {
                ret = min(ret, cnt + (int)word2.size() - j);
            }
            else {
                ret = min(ret, cnt + (int)word1.size() - i);
            }
            return;
        }
//        printf("%d %d %d\n", i, j, cnt);
        tag[i][j] = min(tag[i][j], cnt);
        if(word1[i] == word2[j]) {
            if(tag[i + 1][j + 1] <= cnt) return;
            solve(word1, word2, i + 1, j + 1, cnt);
            return;
        }
        if(tag[i + 1][j + 1] > cnt + 1) {
            solve(word1, word2, i + 1, j + 1, cnt + 1); // 替换
        }
        if(tag[i + 1][j] > cnt + 1) {
            solve(word1, word2, i + 1, j, cnt + 1);     // 删除
        }
        if(tag[i][j + 1] > cnt + 1) {
            solve(word1, word2, i, j + 1, cnt + 1);     // 增加
        }
    }
};

 

// dp
class Solution {
public:
    int minDistance(const string &word1, const string &word2) {
        vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1, 1e9));
        for(int i = 0; i <= word1.size(); ++ i) {
            dp[i][0] = i;
        }
        for(int i = 0; i <= word2.size(); ++ i) {
            dp[0][i] = i;
        }
        for(int i = 1; i <= word1.size(); ++ i) {
            for(int j = 1; j <= word2.size(); ++ j) {
                dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + 1;
                dp[i][j] = min(dp[i][j], dp[i - 1][j - 1] + (word1[i - 1] != word2[j - 1]));
            }
        }
        return dp.back().back();
    }
};

 

leetcode 编辑距离 困难

上一篇:osg旋转


下一篇:磁盘空间不够,来下载阿里云盘,速度也挺不错的哟,再在本机挂个云盘,nice~