题目描述
字符串有三种编辑操作:插入一个字符、删除一个字符或者替换一个字符。 给定两个字符串,编写一个函数判定它们是否只需要一次(或者零次)编辑。
示例:
示例1:
输入:
first = “pale”
second = “ple”
输出:
True
示例 2:
输入:
first = “pales”
second = “pal”
输出:
False
递归
对于两字符串长度差超过1的情况,显然不可能通过一次编辑就可以让它们相同,所以直接返回false。
接下来就只需要考虑长度差在1以内的情况。用两个指针指向两字符串的开头,若出现了不相同的情况则记录下来,若之后再出现不同的字符则直接返回false。第一次发现不同字符之后可以有三种操作跳过first的字符(相当于删除first[i])、跳过second的当前字符(相当在first中填充了一个与当前second[i]相同的字符)、两个指针都向后移动一步(相当于修改一个字符)。
递归终止条件就是指针到达了边界,此时若是两个指针一起到达边界意味着只出现过一个或零个不同的元素返回ture,若是其中一个到达边界一个还未到达边界,则可能出现了以下几种情况:
- 两字符串长度相同,没有进行过任何操作或者进行过修改操作。
- 两字符串长度不同,没有进行过操作。
- 两字符串长度不同,进行过操作。
这些情况只需要考虑之前是否进行过操作,若操作过则返回false否则返回true。
public static boolean oneEditAway(String first, String second) {
if (Math.abs(first.length() - second.length()) > 1)
return false;
return oneEditAwayHelp(first, second, 0, 0, false);
}
private static boolean oneEditAwayHelp(String first, String second, int i, int j, boolean flag) {
if (i == first.length() && j == second.length()) {
return true;
} else if (i == first.length() || j == second.length()){
return !flag;
}
if (first.charAt(i) != second.charAt(j)) {
if (flag == true)
return false;
boolean skipI = oneEditAwayHelp(first, second, i + 1, j, true);
boolean skipJ = oneEditAwayHelp(first, second, i, j + 1, true);
boolean skipTwo=oneEditAwayHelp(first, second, i + 1, j + 1, true);
return skipI || skipJ || skipTwo;
} else return oneEditAwayHelp(first, second, i + 1, j + 1, flag);
}