问题描述
小U和小R有两个字符串,分别是SS和TT,现在小U需要通过对SS进行若干次操作,使其变成TT的一个前缀。操作可以是修改SS的某一个字符,或者删除SS末尾的字符。现在你需要帮助小U计算出,最少需要多少次操作才能让SS变成TT的前缀。
测试样例
样例1:
输入:
S = "aba", T = "abb"
输出:1
样例2:
输入:
S = "abcd", T = "efg"
输出:4
样例3:
输入:
S = "xyz", T = "xy"
输出:1
样例4:
输入:
S = "hello", T = "helloworld"
输出:0
样例5:
输入:
S = "same", T = "same"
输出:0
问题理解
我们需要通过对字符串 S 进行若干次操作,使其变成字符串 T 的一个前缀。操作可以是修改 S 的某一个字符,或者删除 S 末尾的字符。目标是计算出最少需要多少次操作。
数据结构选择
由于我们只需要处理字符串的前缀和字符的修改,不需要复杂的数据结构,直接使用字符串的基本操作即可。
算法步骤
- 初始化操作次数:从0开始。
- 遍历字符串:同时遍历
S和T,直到其中一个字符串遍历完。 - 比较字符:如果当前字符相同,继续遍历下一个字符;如果不同,则需要进行一次修改操作,并继续遍历。
- 处理剩余字符:如果
S遍历完而T还有剩余字符,则需要删除S的剩余部分,每删除一个字符计为一次操作。 - 返回操作次数:最终的操作次数即为最少需要的操作次数。
def solution(S: str, T: str) -> int:
# 初始化操作次数
operations = 0
# 遍历字符串,直到其中一个字符串遍历完
i = 0
while i < len(S) and i < len(T):
# 如果当前字符相同,继续遍历下一个字符
if S[i] == T[i]:
i += 1
else:
# 如果不同,则需要进行一次修改操作,并继续遍历
operations += 1
i += 1
# 如果S还有剩余字符,需要删除这些字符
if i < len(S):
operations += len(S) - i
# 返回操作次数
return operations
if __name__ == '__main__':
print(solution("aba", "abb") == 1)
print(solution("abcd", "efg") == 4)
print(solution("xyz", "xy") == 1)
print(solution("hello", "helloworld") == 0)
print(solution("same", "same") == 0)
当前算法分析
当前的算法是一个线性时间复杂度的算法,时间复杂度为 O(n),其中 n 是 S 和 T 中较短的那个字符串的长度。这个复杂度已经相当不错了,但在某些情况下,我们可以进一步优化代码的可读性和简洁性。
优化思路
- 减少不必要的变量:当前代码中使用了一个变量
i来遍历字符串,这个变量是必要的。但我们可以在遍历过程中直接计算操作次数,减少额外的变量。 - 简化条件判断:当前代码中的条件判断较为清晰,但可以进一步简化逻辑,使其更加紧凑。
优化后的代码
def solution(S: str, T: str) -> int:
# 初始化操作次数
operations = 0
# 遍历字符串,直到其中一个字符串遍历完
for i in range(min(len(S), len(T))):
# 如果当前字符不同,则需要进行一次修改操作
if S[i] != T[i]:
operations += 1
# 如果S还有剩余字符,需要删除这些字符
operations += len(S) - min(len(S), len(T))
# 返回操作次数
return operations
if __name__ == '__main__':
print(solution("aba", "abb") == 1)
print(solution("abcd", "efg") == 4)
print(solution("xyz", "xy") == 1)
print(solution("hello", "helloworld") == 0)
print(solution("same", "same") == 0)
个人思考及易错点
要懂得如何处理边界条件,在遍历字符串时,错误地使用 len(S) 作为遍历的上限,而不是使用 min(len(S), len(T))。在计算操作次数时,要清晰累加操作次数,在处理剩余字符时也应该累加删除操作的次数。
今天也刷了一题(^-^)V