程序员面试经典——01.05. 一次编辑

01.05. 一次编辑

中等

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

示例 1:

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

示例 2:

输入: 
first = "pales"
second = "pal"
输出: False
1.尝试分情况处理(失败)
/**
思路:共涉及三种操作,一种不操作情况(两字符串相等)
    前置判断:排查两字符串相等的情况
    一、插入一个字符 || 二、删除一个字符
        实际中插入或者删除其中一个字符串的字符,只是它们的顺序不一致导致需要的操作。
        也就是说只要顺序处理得当,两种操作可合并

    三、替换一个字符
 */
class Solution {
    public boolean oneEditAway(String first, String second) {
        //不操作情况
        if(first.equals(second) || (first.length() == 0 && second.length() == 1) || (second.length() == 0 && first.length() ==1)){
            return true;
        }
//        //一、插入一个字符 || 二、删除一个字符(合并)
        if(Math.abs(first.length() - second.length()) == 1){
            char[] firstChar = first.toCharArray(), secondChar = second.toCharArray();
            int length = Math.min(secondChar.length, firstChar.length);
            int n = 0,m = 0;
            for (int i = 0; i < length; i++) {
                if (firstChar[n] != secondChar[m]){
                    if(firstChar.length > secondChar.length){
                        n += 1;
                    }else {
                        m += 1;
                    }
                }
                n += 1;
                m += 1;
                if(Math.abs(n - m) > 1){
                    return false;
                }
            }
            return Math.abs(n - m) == 1;
        }
        //三、替换一个字符,遍历任意一个字符串
        else if(first.length() - second.length() == 0){
            int count = 0;
            for (int i = 0; i < first.length(); i++) {
                if(first.charAt(i) != second.charAt(i)){
                    count += 1;
                }
            }
            return count == 1;
        }
        return false;
    }
}

未通过测试用例

解答错误
1124 / 1146 个通过的测试用例

官方题解
输入
first =
"a"
second =
"ab"

添加到测试用例
输出
false
预期结果
true
2.双指针
/**100.00%
双指针:
题意:
    1.需要考虑三种可能的编辑操作:插入、删除和替换。
    2.问题要求判断两个字符串是否需要进行最多一次编辑,就可以使它们相同。

分析思路:
    1.首先,比较两个字符串长度差异和字符差异。有助于确定它们是否可以通过最多一次编辑变得相同。
    2.如果两个字符串的长度差异 > 1,则一定需要多次编辑,直接返回false。
    3.在长度相差为1的情况下,分别考虑长度短和长度长的字符串之间的关系:
        如果长度短的字符串是由长度长的字符串通过一个字符的删除得到的,那么最多只需要一次编辑操作。
        如果长度长的字符串是由长度短的字符串通过一个字符的插入得到的,那么最多也只需一次编辑操作。
        遍历两个字符串进行比较,当发现字符不同时,记录编辑次数,并根据长度的差异移动指针。
        最后检查结束后的编辑次数,验证是否只需要一次编辑。

代码实现思路:
    1.前置判断:比较两个字符串长度差异,差异 > 1,之间return false。
    2.初始化两个指针n,m分别指向两个字符串的起始位置,再初始化变量editCount记录编辑次数
    3.遍历两个字符串进行比较:
        遇到不同字符,先增加编辑次数,并根据长度的差异移动指针。
        如果字符相同,继续向后移动指针。
    4.最后遍历完成后检查编辑次数以判断是否为一次编辑。

 */
class Solution {
    public boolean oneEditAway(String first, String second) {
        int length1 = first.length(),length2 = second.length();
        //前置判断
        if(Math.abs(length1 - length2) > 1) return false;

        //指针及变量赋值
        int editCount = 0,n = 0,m = 0;
        //遍历分情况判断
        while(n < length1 && m < length2){
            if(first.charAt(n) != second.charAt(m)){
                //发现字符不同,编辑数+1
                editCount += 1;
                //合理判断,满足则无需判断
                if(editCount > 1) return false;
                //如果first.length()比second.length()要长,则让n += 1;
                if(length1 > length2){
                    n += 1;
                }
                //如果first.length()比second.length()要短,则让m += 1;
                else if(length1 < length2){
                    m += 1;
                }
                //如果两个都是一样长,则两个都 + 1
                else{
                    n += 1;
                    m += 1;
                }
            }
            //相同,则继续往下遍历
            else{
                n += 1;
                m += 1;
            }
        }

        //检查如果有一个字符串遍历完了,此时双指针均指向两次数最末,且编辑次数最多为1,则返回true
        if(n == length1 && m == length2) return editCount <= 1;

        //处理空字符串和一个字符的情况
        if(n == length1 && m == length2 - 1 || n == length1 - 1 && m == length2){
            return editCount == 0 || editCount == 1;
        }
        return false;
    }
}

注:

​ 1.while条件下两个变量对应字符串长度都需要判断

​ 2.除特殊情况外,正常走出循环两个指针肯定是指向两个字符串最末,因此这里需要

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值