最少前缀操作问题 | 豆包MarsCode AI刷题

74 阅读3分钟

问题描述

小U和小R有两个字符串,分别是S和T,现在小U需要通过对S进行若干次操作,使其变成T的一个前缀。操作可以是修改S的某一个字符,或者删除S末尾的字符。现在你需要帮助小U计算出,最少需要多少次操作才能让S变成T的前缀。

分析

我们需要实现以下操作:

  • 将字符串 S 变成字符串 T 的一个前缀。

  • 修改字符:如果 S 和 T 在相同位置的字符不同,可以将 S 中的字符修改为 T 中的字符。

  • 删除字符:如果 S 比 T 长,可以删除 S 末尾的字符,使其长度与 T 的前缀长度一致。

  • 需要计算出最少的修改和删除操作次数,使得 S 变成 T 的前缀。

处理

  • 首先计算字符串 S 和 T 的长度 l1 和 l2

  • 初始化 times 变量,用于记录操作次数。

  • 处理边界条件:

    • 如果 S 为空字符串,则需要 T 的长度次操作(即添加 T 的所有字符)。
    • 如果 T 为空字符串,则需要 S 的长度次操作(即删除 S 的所有字符)。
  • 如果 S 的长度小于等于 T 的长度:

    • 遍历 S 和 T 的相同位置的字符,如果字符不同,则增加 times
  • 如果 S 的长度大于 T 的长度:

    • 遍历 T 的长度范围内的字符,如果字符不同,则增加 times
    • 最后,增加 S 比 T 多出的字符数(即删除 S 的尾部字符)

代码

  • l1 = len(str1) 和 l2 = len(str2):计算字符串 S 和 T 的长度。
  • times = 0:初始化操作次数。
  • if l1 == 0 和 elif l2 == 0:处理 S 或 T 为空字符串的情况。
  • elif l1 <= l2:遍历 S 和 T 的相同位置的字符,如果字符不同,则增加 times
  • elif l1 > l2:遍历 T 的长度范围内的字符,如果字符不同,则增加 times,最后增加 S 比 T 多出的字符数。
def check(str1: str,str2: str):
    l1 = len(str1)
    l2 = len(str2)
    times = 0
    if l1 == 0:
        times = l2
    elif l2 == 0:
        times = l1
    elif l1 <= l2:
        for i in range(0, l1):
            if str1[i] != str2[i]:
                times += 1
    elif l1 > l2:
        for i in range(0, l2):
            if str1[i] != str2[i]:
                times += 1
        times += (l1 - l2)
    return times
def solution(S: str, T: str) -> int:
    return check(S,T)

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)

总结、优化

  • 使用 zip 函数简化字符比较的逻辑。
  • 合并 l1 <= l2 和 l1 > l2 的逻辑。
# 计算最少操作次数
    for c1, c2 in zip(str1, str2):
        if c1 != c2:
            times += 1

zip(str1, str2) 可以将两个可迭代对象(如字符串、列表等)的元素一一配对,返回一个迭代器。这个迭代器生成的是元组,每个元组包含来自两个可迭代对象的对应元素。