Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题目描述
- 字符串有三种编辑操作:插入一个字符、删除一个字符或者替换一个字符。 给定两个字符串,编写一个函数判定它们是否只需要一次(或者零次)编辑。
示例 1
输入:
first = "pale"
second = "ple"
输出: True
示例 2
输入:
first = "pales"
second = "pal"
输出: False
思路分析
- 字符串的变换一共有三种:插入一个字符、删除一个字符和替换一个字符,其中插入和删除字符都会改变一个字符串的长度。
- 我们要维护字符串修改的次数,所以在这里可以用动态规划也可以用递归回溯剪枝。具体见 AC 代码。
- 例如,以 字符串为标准。
- 当 与 在对应位置 字符不同时。
删除该位置上的字符,此时 对应的 变为 + 1 , 对应的 不变。插入该位置上 字符对应的字符,此时 对应的 不变, 对应的 变为 + 1 。替换任意字符对应位置的字符即可,此时 和 对应的 都要变为 + 1。
AC 代码
class Solution {
char[] f;
char[] s;
int nf;
int ns;
public boolean oneEditAway(String first, String second) {
f = first.toCharArray(); // 转为字符数组,访问字符数组速度要远快于访问字符串的速度.
s = second.toCharArray();
nf = f.length;
ns = s.length;
if (Math.abs(nf - ns) >= 2) return false;
return dfs(0,0,0);
}
private boolean dfs(int index_f, int index_s, int count) {
if (count >= 2) return false; // 当修改字符的次数大于等于 2 次时不符合题意.
if (index_f >= nf && index_s >= ns) return true; // 修改次数小于 2 , 且两字符一致.
else if (index_f >= nf) {
if (count == 1) return false; // 此处肯定要进行一次插入或者删除,之前已经有过一次修改,所以不符合题意.
int sub = ns - index_s;
return sub <= 1; // 所要修改的次数应该要小于等于 1 次.
} else if (index_s >= ns) { // 分析同上.
if (count == 1) return false;
int sub = nf - index_f;
return sub <= 1;
}
if (f[index_f] == s[index_s]) {
return dfs(index_f + 1, index_s + 1,count);
} else { // 以下是对 f 进行操作.
return dfs(index_f + 1, index_s, count + 1) || // 删除.
dfs(index_f, index_s + 1, count + 1) || // 插入.
dfs(index_f + 1, index_s + 1, count + 1); // 替换.
}
}
}
总结
- 这道题按照常规思路应该是用动态规划来做的,但是刚好可以可以用回溯解决,且回溯方法相比于动态规划更简单、更容易理解!