前言:
“一次编辑”的题目是在力扣题库上的程序员面试经典(第6版)中。我是使用Python3编写的解法,性能算不上好,在此仅仅只是阐述一下解法编程思想。仅供参考~
解法上可能会跟别人相同,所以要是看不懂下面的阐述的话可以去力扣对应的题目上查看其他人的解题思路~
问题描述:
题目的要求是:字符串有三种编辑操作:插入一个字符、删除一个字符或者替换一个字符。 给定两个字符串,编写一个函数判定它们是否只需要一次(或者零次)编辑。
力扣的演示例子如下:
示例1:
输入:
first = "pale"
second = "ple"
输出: True
示例2:
输入:
first = "pales"
second = "pal"
输出: False
解法思路:
通过题目可以知道,题目的要求只是判定两个字符串之间(下面用A与B表示这两个字符串)是否只需要一次(或者零次)编辑;而编辑有三种方式:删除、插入、替换。除此之外还有一种情况就是A与B之间没做修改,也就是A==B。而对于删除、插入的操作,编辑一次只会使得A和B的长度之差保持在1之内。而替换或不编辑则不会改变A和B的长度,就是说A的长度等于B的长度。
因此对于A和B之间的长度之差上的情况基本上是会有三种情况:
- 第一种最简单,就是A和B的长度之差超过1,而这种情况发生的原因大致有:
- A和B之间是通过两次或两次以上的编辑而成的,如“low”与“yellow”——不符合要求
所以说当A和B的长度之差大于等于2时,即不符合题目要求,返回False。
- 第二种则是A和B的长度相等,这种情况发生的原因大致有:
- 替换两者之间的一个字符,如“blue”与“alue”——符合要求
- 两者之间没有编辑过,如“red”与“red”——符合要求
- A和B是通过两次或两次以上编辑而成的,如“red”与“abc”——不符合要求
故只需查看两者之间不一样的字符次数即可,超过一次返回False,否则返回True
一次编辑:替换
0 1 2
r e d
r e s
√ √ ×
只替换了一次,返回True
0 1 2
q e d
a e s
× √ ×
只替换了两次,返回False
0 1 2
a b c
d e s
× × ×
不止替换一次,返回False
- 第三种是 A和B的长度之差等于1,这种情况发生的原因大致有:
- 两者通过删除或插入的编辑一次,如“boy”与“boys”——符合要求
- 两者是通过两次或两次以上编辑而成的,如“ad”与“adce”——不符合要求
此时,假如对A进行一次删除得到B,那么对于B来说就是对B进行一次插入得到A,故删除和插入的操作可以都只当成删除或者插入。
以当成插入来说,从左往右依次比对字符,出现第一次字符不匹配时,字符串长的一方的下标要加一,然后再与字符串短的一方的当前位置继续比对下去,如果又发生字符不匹配,返回False,否则返回True。
匹配成功的情况:
匹配不成功的情况:
程序流程图:
相关代码:
class Solution:
def oneEditAway(self, first: str, second: str) -> bool:
# 判断是否只进行一次插入或删除操作
def isOneInRm(maxList,minList,minLen):
index=0 # 字符串长的所对应的下标
is_rm_ap=False # 是否是第一次删除或者插入
# 遍历字符串短的
for i in range(minLen):
# 如果对应下标的字符不匹配
if minList[i] != maxList[index]:
if is_rm_ap:
# 之前已经插入或删除过了
return False
else:
# 之前还没插入或删除过了
is_rm_ap=True
index+=1
# 继续比对字符串长的后一个与字符串短的的当前位置是否匹配
if maxList[index]!=minList[i]:
# 还是不匹配,说明超过了一次编辑
return False
index+=1
return True
first_len=len(first)
second_len=len(second)
if abs(first_len-second_len)>=2:
# 两者的长度超过1,说明至少操作了两次
return False
else:
# 遍历字符串长度短的,若出现相同的下标对应的字符不一致时,说明有删除或者插入的操作
# 此时需要将字符串长的下标加一再跟短的字符串进行匹配
# 若再次出现字符串下标不一致的情况,说明至少操作了两次
if first_len==second_len:
# 操作有替换或保持不变
is_re=False
for i in range(first_len):
if first[i] != second[i]:
if is_re:
# 之前已经替换过了
return False
else:
# 之前还没替换
is_re=True
return True
else:
# 操作只有插入或删除
if first_len>second_len:
return isOneInRm(first,second,second_len)
if first_len<second_len:
return isOneInRm(second,first,first_len)