字符串有三种编辑操作:插入一个字符、删除一个字符或者替换一个字符。 给定两个字符串,编写一个函数判定它们是否只需要一次(或者零次)编辑。
示例 1:
输入:
first = "pale"
second = "ple"
输出: True
示例 2:
输入:
first = "pales"
second = "pal"
输出: False
----------------------------------------------------------------------------------------------------------------------
分析历程:
看到这道题,我首先脑子里思路是很明确的,暴力而又不失一般性的解法:
1. 首先可分析出,如果两个字符串之间的长度之差大于1,那么直接返回即可,因为无论插入,删除或者替换一个字符都不满足提议;
2. 其次分析出替换与删除和插入是不一样的。换句话说,替换的前提是两个字符串长度必须相等。而插入与删除的两个字符串的差只可能为1;
根据上面分析的思路,编写了相关的代码,可谓思路很清晰。
但emmmmmm,检测上一共大约1400多个实例,但是就有那么几个通不过,我仔细看了没通过的代码,也不知道为啥,按照我的想法与实现,应该是能通过的。本来想放上来,鉴于代码有点多,肯定有更好的解法;
--------------------------------------------------------------------------------------------------------------------------------
在解答区中存在一种“双指针”的解法,非常的巧妙:
它分别从两个字符串的两端分别向中间进行遍历,遇到不一样的则停止遍历,这样就非常巧妙的将上面不同的情况融合在一起了。上面分情况考虑虽然思路简单,但是往往非常容易忽视一些边界情况;
这里注意临界条件,实际上这个临界条件是很好理解的;因为我们是在不符合条件时退出循环。从左往右遍历退出循环时是多往右前进,而从右往左遍历退出循环时是多往左前进,这就不难理解为啥最后条件是j-i<1 && k-i<1;
class Solution {
public:
bool oneEditAway(string first, string second) {
//双指针法,分别从两边向中间扫描,遇到不一样则停止
if(first == second)
return true;
const int first_len = first.size();
const int second_len = second.size();
if(abs(first_len-second_len)>1)
return false;
int i = 0, j = first_len-1, k = second_len-1;
while(i<first_len && i<second_len && first[i]==second[i]){
i++;
}
while(j >=0 && k>=0&& first[j] == second[k])
{
j--;
k--;
}
return j-i<1 && k-i<1;
}
};