2019-08-05 EP161 One Edit Distance

image.png

这个道题目一咋看,很多人肯定会觉得直接DP,因为这种是典型的DP的题目,初始条件很容易想到,推导式也很容易想到,写起来清晰明了

class Solution {
public:
    bool isOneEditDistance(string s, string t) {
        vector<vector<int>> dp(s.size() + 1, vector<int>(t.size() + 1, 0));
        
        for (int i = 0; i <= s.size(); i++) {
            dp[i][0] = i;
        }
        
        for (int j = 0; j < t.size(); j++) {
            dp[0][j] = j;
        }
        
        for (int i = 1; i <= s.size(); i++) {
            for (int j = 1; j <= t.size(); j++) {
                if (s[i - 1] == t[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    dp[i][j] = min(dp[i - 1][j], min(dp[i][j - 1], dp[i - 1][j - 1])) + 1;
                }
            }
        }
        
        return dp[s.size()][t.size()] == 1;
    }
};

上面写的二维数组可以通过滚动数组的方式降到1维,空间复杂度O(N),时间复杂度O(N^2)

仔细想一想,其他用DP的方式过重了,为什么呢?因为计算了所有的substring 是不是满足one edit distance,可以通过更简单直接的方法来优化这个问题,如下面这个解法,关键点是

  • 如果两个string 长度相等,那么有且只有其中的个char值不一样
  • 如果两个string 长度不相等,那么长度相差应该有且等于1,且不同的地方之后应该和原来的string相等
class Solution {
public:
    bool isOneEditDistance(string s, string t) {
        int m = s.size(), n = t.size();
        if (m > n) {
            return isOneEditDistance(t, s);
        }
        for (int i = 0; i < m; i++) {
            if (s[i] != t[i]) {
                if (m == n) {
                    return s.substr(i + 1) == t.substr(i + 1);
                }
                return s.substr(i) == t.substr(i + 1);
            }
        }
        return m + 1 == n;
    }
};

推荐阅读更多精彩内容