LeetCode 第161题:相隔为1的编辑距离
题目描述
给定两个字符串 s
和 t
,判断他们的编辑距离是否为 1。
注意:
- 满足编辑距离为 1 有三种可能的情形:
- 往
s
中插入一个字符得到t
- 从
s
中删除一个字符得到t
- 在
s
中替换一个字符得到t
- 往
难度
中等
题目链接
示例
示例 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
s
和t
由小写字母,大写字母和数字组成
解题思路
方法:分情况讨论
根据字符串长度的差异分为两种情况讨论:
- 如果两个字符串长度之差大于1,则一定不满足条件,直接返回false
- 如果两个字符串长度相等,则只可能是替换操作,遍历检查不同字符的个数
- 如果两个字符串长度相差为1,则只可能是插入或删除操作,遍历检查
关键点:
- 分情况讨论不同的编辑操作
- 确保长度较短的字符串在前,长度较长的在后,简化逻辑
- 统计差异的字符数,确保只有一处差异
时间复杂度: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 ms | 36.2 MB | 实现简洁,性能适中 |
Python | 46 ms | 15.1 MB | 代码最简洁 |
C++ | 4 ms | 6.4 MB | 性能最优 |
补充说明
代码亮点
- 通过分情况讨论简化问题
- 保证较短字符串在前,简化逻辑处理
- 使用字符串截取操作简化代码
常见错误
- 没有考虑字符串长度差大于1的情况
- 没有考虑两个字符串完全相同的情况(应返回false)
- 没有正确处理字符串长度不等的情况