LeetCode——面试题 01.05. 一次编辑

题目描述

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

示例 1:

输入:
first = “pale”
second = “ple”
输出: True

示例 2:

输入:
first = “pales”
second = “pal”
输出: False

答案

我的答案

class Solution {
    public boolean oneEditAway(String first, String second) {
        // 判断是否相同
        if (first.equals(second)){
            return true;
        }
        int f = first.length();
        int c = second.length();
        // 如果长度差大于1返回false
        if (Math.abs(f-c)>1){
            return false;
        }else if (Math.abs(f-c)==1){
            // 如果长度差等于1
            int j = 0;
            int x = 0;
            // 如果f大于c
            if (f>c){
                for (int i = 0; i < second.length(); i++) {
                    if (second.charAt(i)!=first.charAt(j)){
                        i--;
                        x++;
                    }
                    if (x>1){
                        return false;
                    }
                    j++;
                }
            }else {
                for (int i = 0; i < first.length(); i++) {
                    if (second.charAt(j)!=first.charAt(i)){
                        i--;
                        x++;
                    }
                    if (x>1){
                        return false;
                    }
                    j++;
                }
            }
            return true;
        }else {
            // 如果f等于c
            int j = 0;
            for (int i = 0; i < first.length(); i++) {
                if (first.charAt(i)!=second.charAt(i)){
                    j++;
                }
                if (j>1){
                    return false;
                }
            }
            return true;
        }

    }
}

官方答案

分情况讨论

假设字符串 first 和 second 的长度分别是 m 和 n。

如果 first 和 second 需要一次编辑,则可能有三种情况:

  • 往 first 中插入一个字符得到 second,此时 n−m=1,second 比 first 多一个字符,其余字符都相同;

  • 从 first 中删除一个字符得到 second,此时 m−n=1,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 则不符合一次编辑,遍历结束时如果两个字符串的下标之差不大于 1 则符合一次编辑。

当 m=n 时,同时遍历 first 和 second,比较相同下标处的字符是否相同。如果字符不同的下标个数不超过 1,则符合一次编辑或零次编辑。
代码:

class Solution {
    public boolean oneEditAway(String first, String second) {
        int m = first.length(), n = second.length();
        if (n - m == 1) {
            return oneInsert(first, second);
        } else if (m - n == 1) {
            return oneInsert(second, first);
        } else if (m == n) {
            boolean foundDifference = false;
            for (int i = 0; i < m; i++) {
                if (first.charAt(i) != second.charAt(i)) {
                    if (!foundDifference) {
                        foundDifference = true;
                    } else {
                        return false;
                    }
                }
            }
            return true;
        } else {
            return false;
        }
    }

    public boolean oneInsert(String shorter, String longer) {
        int length1 = shorter.length(), length2 = longer.length();
        int index1 = 0, index2 = 0;
        while (index1 < length1 && index2 < length2) {
            if (shorter.charAt(index1) == longer.charAt(index2)) {
                index1++;
            }
            index2++;
            if (index2 - index1 > 1) {
                return false;
            }
        }
        return true;
    }
}

复杂度分析

  • 时间复杂度:O(m+n),其中 m 和 n 分别是字符串 first 和 second 的长度。当 ∣m−n∣≤1 时,需要遍历两个字符串各一次。
  • 空间复杂度:O(1)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值