题目描述
字符串有三种编辑操作:插入一个字符、删除一个字符或者替换一个字符。 给定两个字符串,编写一个函数判定它们是否只需要一次(或者零次)编辑。
示例 1:
输入:
first = "pale"
second = "ple"
输出: True
示例 2:
输入:
first = "pales"
second = "pal"
输出: False
这道题一开始我是怎么也想不出啥办法,甚至还想用哈希表去搞,最后放弃了。这样大大增加了重复的步骤,根本不符合这道题的思路,于是去借鉴大佬的解法。不得不说宫水大佬的方法就是独树一帜,把简洁体现地淋漓尽致。
思路是用双指针,在此之前先判断一些东西:
- 如果两字符串长度相差大于1,则无法通过一次编辑使之相同,返回false;
- 这里强制令a的长度小于b,如果出现a长度大于b,则返回一个交换参数的原方法,这一行代码可谓是将简洁发挥到了极致,无需再去写什么判断语句。
主要代码里,双指针用于判断当前位置的两个字符是否相同,相同则都往后移,如果不同,分两种情况:
- 如果a与b 的长度相同,则代表要通过修改达到相同,这种情况下,两个指针均往后移,同时计数器加1;
- 如果a与b长度不同,这里一定是a<b,则代表a中要增加字符串,所以b的指针后移,同时计数器加1;
最后如果计数器的值不大于1,则返回true,否则返回false。
class Solution {
public boolean oneEditAway(String a, String b) {
int n = a.length(),m = b.length();
//如果m和n的差值大于1,则返回false
if(Math.abs(m-n)>1)return false;
//强制令n<m
if(n>m) return oneEditAway(b,a);
//双指针
int i=0,j=0,cnt=0;
while(i<n && j<m){
char c1 = a.charAt(i), c2 = b.charAt(j);
if(c1==c2){ i++;j++;}
//不相同情况下,分类讨论
else{
//长度相同,则代表修改
if(n==m) {i++;j++;cnt++;}
//长度不同,则代表增删
else {j++;cnt++;}
}
}
return cnt<=1;
}
}
分类讨论的思想很重要,理解方法容易,自己想出方法难,到现在为止,我大概有了一些经验:对于两个整体上有序的序列,要想从中操作某一个无序的局部,双指针这时候就派上用场了。