题目地址:
https://leetcode.com/problems/one-edit-distance/
给定两个字符串和,问可否由下列三种变换变为:
1、在中插入一个字符;
2、在中删除一个字符;
3、在中替换一个字符。
如果可以就返回true,否则返回false。
首先排除掉与长度差大于等于或者和相等的情况,这两种情况下都是不可能变为的,直接返回false。
接着,从左向右同时扫描和,如果遇到相同字符,那就继续扫描,否则,如果遇到不同字符,那么必然要经过三种变换其中的一种,来”修复“这种不同,而用哪一种变换取决于和的长度的比较。如果和一样长,那就是变换,如果比长,那就是变换,如果比短,那就是变换;无论哪一种,都只需要继续比较和的剩余子串就可以了。代码如下:
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));
}
}
}
时间复杂度,空间。
算法正确性证明:
首先如果两个字符串长度大于或者两个字符串相等的时候,返回false,这一点没有问题。
接下来,当while循环退出时,有三种可能性,
1、已经走到头;
2、已经走到头;
3、。
如果的长度小于的话,那么要么要么,并且的长度比大;如果是,那么说明应该是空串,也就是删去最后一个字母应该会变成;如果是,那么就要把在的位置新加一个字母,接着比之后的子串和是否相等。无论怎样,都可以写为return s.substring(i).equals(t.substring(j + 1));
;
如果的长度大于的话,证明是类似的;至于两者长度相等时的证明是显然的。综上,算法正确。