LeetCode第161题_相隔为1的编辑距离

LeetCode 第161题:相隔为1的编辑距离

题目描述

给定两个字符串 st,判断他们的编辑距离是否为 1。

注意:

  • 满足编辑距离为 1 有三种可能的情形:
    • s 中插入一个字符得到 t
    • s 中删除一个字符得到 t
    • s 中替换一个字符得到 t

难度

中等

题目链接

点击在LeetCode中查看题目

示例

示例 1:

输入: s = "ab", t = "acb"
输出: true
解释: 可以将 'c' 插入字符串 s 来得到 t。

示例 2:

输入: s = "cab", t = "ad"
输出: false
解释: 无法通过 1 步操作使 s 变为 t。

示例 3:

输入: s = "1203", t = "1213"
输出: true
解释: 可以将字符串 s 中的 '0' 替换为 '1' 来得到 t。

提示

  • 0 <= s.length, t.length <= 10^4
  • st 由小写字母,大写字母和数字组成

解题思路

方法:分情况讨论

根据字符串长度的差异分为两种情况讨论:

  1. 如果两个字符串长度之差大于1,则一定不满足条件,直接返回false
  2. 如果两个字符串长度相等,则只可能是替换操作,遍历检查不同字符的个数
  3. 如果两个字符串长度相差为1,则只可能是插入或删除操作,遍历检查

关键点:

  1. 分情况讨论不同的编辑操作
  2. 确保长度较短的字符串在前,长度较长的在后,简化逻辑
  3. 统计差异的字符数,确保只有一处差异

时间复杂度:O(n),其中n是较短字符串的长度。
空间复杂度:O(1),只使用常数额外空间。

代码实现

C# 实现

public class Solution {
    public bool IsOneEditDistance(string s, string t) {
        int sLen = s.Length;
        int tLen = t.Length;
        
        // 确保s是较短的字符串
        if (sLen > tLen) {
            return IsOneEditDistance(t, s);
        }
        
        // 如果长度差大于1,不可能相隔为1的编辑距离
        if (tLen - sLen > 1) {
            return false;
        }
        
        for (int i = 0; i < sLen; i++) {
            if (s[i] != t[i]) {
                // 如果长度相等,尝试替换
                if (sLen == tLen) {
                    return s.Substring(i + 1) == t.Substring(i + 1);
                }
                // 如果长度不等,尝试插入(删除)
                return s.Substring(i) == t.Substring(i + 1);
            }
        }
        
        // 如果没有差异,检查长度差是否为1
        return sLen + 1 == tLen;
    }
}

Python 实现

class Solution:
    def isOneEditDistance(self, s: str, t: str) -> bool:
        s_len, t_len = len(s), len(t)
        
        # 确保s是较短的字符串
        if s_len > t_len:
            return self.isOneEditDistance(t, s)
        
        # 如果长度差大于1,不可能相隔为1的编辑距离
        if t_len - s_len > 1:
            return False
        
        for i in range(s_len):
            if s[i] != t[i]:
                # 如果长度相等,尝试替换
                if s_len == t_len:
                    return s[i+1:] == t[i+1:]
                # 如果长度不等,尝试插入(删除)
                return s[i:] == t[i+1:]
        
        # 如果没有差异,检查长度差是否为1
        return s_len + 1 == t_len

C++ 实现

class Solution {
public:
    bool isOneEditDistance(string s, string t) {
        int s_len = s.length();
        int t_len = t.length();
        
        // 确保s是较短的字符串
        if (s_len > t_len) {
            return isOneEditDistance(t, s);
        }
        
        // 如果长度差大于1,不可能相隔为1的编辑距离
        if (t_len - s_len > 1) {
            return false;
        }
        
        for (int i = 0; i < s_len; i++) {
            if (s[i] != t[i]) {
                // 如果长度相等,尝试替换
                if (s_len == t_len) {
                    return s.substr(i + 1) == t.substr(i + 1);
                }
                // 如果长度不等,尝试插入(删除)
                return s.substr(i) == t.substr(i + 1);
            }
        }
        
        // 如果没有差异,检查长度差是否为1
        return s_len + 1 == t_len;
    }
};

性能分析

各语言实现的性能对比:

实现语言执行用时内存消耗特点
C#84 ms36.2 MB实现简洁,性能适中
Python46 ms15.1 MB代码最简洁
C++4 ms6.4 MB性能最优

补充说明

代码亮点

  1. 通过分情况讨论简化问题
  2. 保证较短字符串在前,简化逻辑处理
  3. 使用字符串截取操作简化代码

常见错误

  1. 没有考虑字符串长度差大于1的情况
  2. 没有考虑两个字符串完全相同的情况(应返回false)
  3. 没有正确处理字符串长度不等的情况

相关题目

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值