字符串有三种编辑操作:插入一个英文字符、删除一个英文字符或者替换一个英文字符。给定两个字符串,编写一个函数判断他们是否只需要一次(或者零次)编辑。
示例一:
输入:first="pale",second="ple"
输出:true
示例二:
输入:first="pales",second="pal"
输出:false
方法:分情况讨论
假设字符串first和second的长度分别为m和n。
如果first和second需要一次编辑,则可能有三种情况:
1.往first中插入一个字符得到second,此时n-m==1,second比first多一个字符,其余字符都相等。
2.从first中删除一个字符得到second,此时m-n==1,first比second多一个字符,其余字符都相等。
3.将first中一个字符替换成不同的字符得到second,此时m==n,first和second恰有一个字符不同。
如果first和second需要零次编辑,则m=n且first和second相等。
如果first 和second 需要零次编辑,则m=n 且first 和second 相等。根据上述分析,当符合一次编辑时,first和second 的长度关系可能有三种情况,分别是n−m=1、m−n=1 和 m=n。首先计算 first 和 second 的长度关系,在可能的三种情况中找到对应的一种情况,然后遍历字符串判断是否符合一次编辑或零次编辑。特别地,只有当 m=n 时才需要判断是否符合零次编辑。
如果长度关系不符合上述三种情况,即 ∣m−n∣>1,则不符合一次编辑或零次编辑。
具体实现方法如下。
当 n−m=1 或 m−n=1 时,由于两种情况具有对称性,因此可以定义一个函数统一计算这两种情况。用 longer 表示较长的字符串,shorter 表示较短的字符串,同时遍历两个字符串,比较对应下标处的字符是否相同,如果字符相同则将两个字符串的下标同时加 1,如果字符不同则只将 longer 的下标加 1。遍历过程中如果出现两个字符串的下标之差大于 1 则不符合一次编辑,遍历结束时如果两个字符串的下标之差不大于 11则符合一次编辑。
当 m=n 时,同时遍历 first 和 second,比较相同下标处的字符是否相同。如果字符不同的下标个数不超过 1,则符合一次编辑或零次编辑。
bool oneinsert (const char*shorter,const char*longer)
{int length1=strlen (shorter);int length2=strlen (longer);int index1=0;int index2=0;while (index1<length1&&index2<length2){if (shorter[index1]==longer[index2]){index1++;}index2++;if (index2-index1>1){return false;}}return true;}bool oneEditAway(char* first, char* second){int m = strlen (first);int n = strlen (second);if (m-n==1){return oneinsert(second,first);}else if (n-m==1){return oneinsert(first,second);}else if (m==n){bool founddiffence = false;for (int i=0;i<m;i++){if (first[i]!=second[i]){if (!founddiffence){founddiffence=true;}else{return false;}}}return true;}else{return false;}}时间复杂度:O(N)N=m+n
空间复杂度:O(1)