力扣面试题 01.05. 一次编辑

一次编辑

1.题目要求

字符串有三种编辑操作:插入一个英文字符、删除一个英文字符或者替换一个英文字符。
给定两个字符串,编写一个函数判定它们是否只需要一次(或者零次)编辑。

示例1:

输入: 
first = "pale"
second = "ple"
输出: True

示例2

输入: 
first = "pales"
second = "pal"
输出: False

2.解题思路

通过字符串长度之差的绝对值判断是否符合题目要求

1,绝对值差值 > 1,则为不符合条件的字符串。
2,绝对值差值 = 1,该字符串通过插入、删除操作可实现一次操作。
	 找到字符串长度最大的字符串,轮流删除最大字符串的每个字符后,
	 再与另一个字符串进行比较,只要相等就是符合条件的字符串。
3,绝对值差值 = 0,该字符串通过替换操作可实现一次操作。
	 当 相同下标字符不相等的数量 > 1 时,则为不符合条件的字符串。

3.代码实现

class Solution {
    public boolean oneEditAway(String first, String second) {
        int dif = first.length() - second.length();
        //取绝对值
        // int k = Math.abs( dif );
        int t = ( dif < 0 ) ? -dif : dif;
        char[] ch3 = ( dif < 0 ) ? second.toCharArray() : first.toCharArray();
        char[] ch1 = first.toCharArray();
        char[] ch2 = second.toCharArray();
        //不符合
        if( t > 1 ){
            return false;
        }
        //插入,删除
        if( t == 1 ){
            char[] max = new char[first.length()];
            char[] min = new char[first.length()];
            if( dif < 0 ){
                max = ch2;
                min = ch1;
            }else{
                max = ch1;
                min = ch2;
            }
            for( int i = 0; i < ch3.length; i++ ){
                for( int j = 0; j < max.length-i-1; j++ ){
                    max[j+i]=max[i+j+1];
                }
                max[max.length-1] = ' ';
                System.out.println( String.valueOf(max).trim()+"="+ String.valueOf(min) );
                if( String.valueOf(max).trim().equals( String.valueOf(min) ) ){
                    return true;
                }
                if( dif < 0 ){
                    max = second.toCharArray();
                }else{
                    max = first.toCharArray();
                }
                System.out.println( String.valueOf(max)+"===" );
            }           
            return false;
        }
        //替换
        if( t == 0 ){
            int flag = 0;
            //字符串长度相等
            for( int i = 0; i < first.length(); i++ ){
                // System.out.println(f);
                if( ch1[i]!=ch2[i] ){
                    flag++;
                }
                if( flag > 1 ){
                    return false;
                }
            }
            return true;
        }
        return false;
    }
}

4.最优解法

双指针模拟
为了方便,我们令 a = first、b = second,两者长度为 n 和 m,并让 a 为两者中的长度较短的那个(若 b 较短,则将两者交换)。

接下来是简单的双指针处理(使用 cnt 记录操作次数):

我们最多使用不超过一次的操作,因此如果 ∣n−m∣>1,直接返回 False;
若两者长度差不超过 1,使用 i 和 j 分别指向两字符的最左侧进行诸位检查:
若 a[i]=b[j],让 i 和 j 继续后移进行检查;
若 a[i] != b[j],根据两字符串长度进行分情况讨论:
	若 n = m,说明此时只能通过「替换」操作消除不同,分别让 i 和 j 后移,并对 cnt 进行加一操作;
	若 n != m,由于我们人为确保了 a 更短,即此时是 n < m,此时只能通过对 a 字符串进行「添加」操作来消除不同,此时让 j 后移,i 不动(含义为在 a 字符串中的 i 位置增加一个 b[j] 字符),并对 cnt 进行加一操作。
最终我们根据 cnt 是否不超过 1 来返回结果。

时间复杂度:令 n 和 m 分别为两字符串长度,复杂度为 O(max(n,m))
空间复杂度:O(1)

作者:AC_OIer
class Solution {
    public boolean oneEditAway(String a, String b) {
        int n = a.length(), m = b.length();
        if (Math.abs(n - m) > 1) return false;
        if (n > m) return oneEditAway(b, a);
        int i = 0, j = 0, cnt = 0;
        while (i < n && j < m && cnt <= 1) {
            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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值