【Leetcode】161. One Edit Distance

题目地址:

https://leetcode.com/problems/one-edit-distance/

给定两个字符串sstt,问ss可否由下列三种变换变为tt
1、在ss中插入一个字符;
2、在ss中删除一个字符;
3、在ss中替换一个字符。
如果可以就返回true,否则返回false。

首先排除掉sstt长度差大于等于22或者sstt相等的情况,这两种情况下ss都是不可能变为tt的,直接返回false。

接着,从左向右同时扫描sstt,如果遇到相同字符,那就继续扫描,否则,如果遇到不同字符,那么ss必然要经过三种变换其中的一种,来”修复“这种不同,而用哪一种变换取决于sstt的长度的比较。如果sstt一样长,那就是变换33,如果sstt长,那就是变换22,如果sstt短,那就是变换11;无论哪一种,都只需要继续比较sstt的剩余子串就可以了。代码如下:

public class Solution {
    public boolean isOneEditDistance(String s, String t) {
    	// 如果两个字符串长度之差大于等于2,或者两个字符串相等,
    	// 那s绝对无法通过一次变换变为t,直接返回false
        if (Math.abs(s.length() - t.length()) >= 2 || s.equals(t)) {
            return false;
        }
        
        int i = 0, j = 0;
        while (i < s.length() && j < t.length() && s.charAt(i) == t.charAt(j)) {
            i++;
            j++;
        }
        
        if (s.length() < t.length()) {
            return s.substring(i).equals(t.substring(j + 1));
        } else if (s.length() > t.length()) {
            return s.substring(i + 1).equals(t.substring(j));
        } else {
            return s.substring(i + 1).equals(t.substring(j + 1));
        }
    }
}

时间复杂度O(n)O(n),空间O(1)O(1)

算法正确性证明:
首先如果两个字符串长度大于11或者两个字符串相等的时候,返回false,这一点没有问题。
接下来,当while循环退出时,有三种可能性,
1、ii已经走到头;
2、jj已经走到头;
3、s[i]t[j]s[i]\ne t[j]
如果ss的长度小于tt的话,那么要么11要么33,并且tt的长度比ss11;如果是11,那么说明t[j+1,...]t[j+1,...]应该是空串,也就是tt删去最后一个字母应该会变成ss;如果是33,那么就要把ssii的位置新加一个字母,接着比ss之后的子串和t[j+1,...]t[j+1,...]是否相等。无论怎样,都可以写为return s.substring(i).equals(t.substring(j + 1));
如果ss的长度大于tt的话,证明是类似的;至于两者长度相等时的证明是显然的。综上,算法正确。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章