问题描述
小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中的某个字符,使其匹配T中对应位置的字符。 - 删除操作:可以删除
S中的字符,直到S的长度和T的前缀相匹配。
我们的目标是最小化这些操作次数,使得 S 变成 T 的前缀。
思路
-
前缀匹配:
- 如果
S的某个前缀已经是T的前缀,那么我们可以通过删除S中多余的字符来使其变成T的前缀,删除操作的次数是S的多余部分的长度。 - 如果
S和T的前缀不匹配,我们可以逐字符修改S中的不匹配字符,直到它们的前缀匹配为止。
- 如果
-
最长公共前缀:
-
我们的关键是找到
S和T的最长公共前缀(LCP,Longest Common Prefix)。最长公共前缀的长度L,表示了从头开始两个字符串匹配的部分。之后的字符我们需要进行修改或删除操作。 -
计算出最长公共前缀后,剩下的操作分为:
- 删除操作:从
S的末尾删除剩余部分。 - 修改操作:将
S中与T对应部分的字符修改为T中的字符。
- 删除操作:从
-
-
最少操作:
- 删除部分:如果
S的前缀已经匹配了T,那么删除S中多余的字符。 - 修改部分:如果
S中的某些字符与T不匹配,需要通过修改来使它们匹配。
- 删除部分:如果
解决步骤
-
计算
S和T的最长公共前缀的长度L。 -
对于剩余的部分:
- 如果
S长度大于L,则需要删除S中的多余部分。 - 如果
S的长度小于T,则需要修改S的部分字符,使其成为T的前缀。
- 如果
代码实现
def solution(S: str, T: str) -> int:
# 初始化操作次数
operations = 0
# 遍历字符串 S 和 T
for i in range(min(len(S), len(T))):
if S[i] != T[i]:
operations += 1
# 如果 S 的长度大于 T 的长度,需要删除多余的 S 的字符
if len(S) > len(T):
operations += 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)
测试样例
样例 1
输入:S = "aba", T = "abb"
- 公共前缀:
ab(长度为 2) - 删除操作:
len("aba") - 2 = 1 - 修改操作:
len("abb") - 2 = 1 - 最少操作次数:
1 (删除) + 1 (修改) = 2
输出:1
样例 2
输入:S = "abcd", T = "efg"
- 公共前缀:
""(长度为 0) - 删除操作:
len("abcd") - 0 = 4 - 修改操作:
len("efg") - 0 = 3 - 最少操作次数:
4 (删除) + 3 (修改) = 7
输出:4
样例 3
输入:S = "xyz", T = "xy"
- 公共前缀:
xy(长度为 2) - 删除操作:
len("xyz") - 2 = 1 - 修改操作:
len("xy") - 2 = 0 - 最少操作次数:
1 (删除) + 0 (修改) = 1
输出:1
样例 4
输入:S = "hello", T = "helloworld"
- 公共前缀:
hello(长度为 5) - 删除操作:
len("hello") - 5 = 0 - 修改操作:
len("helloworld") - 5 = 5 - 最少操作次数:
0 (删除) + 0 (修改) = 0
输出:0
样例 5
输入:S = "same", T = "same"
- 公共前缀:
same(长度为 4) - 删除操作:
len("same") - 4 = 0 - 修改操作:
len("same") - 4 = 0 - 最少操作次数:
0 (删除) + 0 (修改) = 0
输出:0
总结
这个问题的核心是找出 S 和 T 的最长公共前缀,基于这个前缀来计算最少的操作次数。通过删除和修改,我们能够有效地将 S 转换成 T 的前缀。