青训营X豆包MarsCode 技术训练营刷题4 | 豆包MarsCode AI 刷题

96 阅读2分钟

问题描述:

给定两个字符串 ST,你可以对字符串 S 进行以下两种操作任意次数:

  1. 修改操作:将 S 中的某一个字符修改为任意字符。
  2. 删除操作:删除 S 末尾的一个字符。

你的目标是通过最少的操作次数,将字符串 S 变为字符串 T 的一个前缀。

请计算将 S 变为 T 的前缀所需的最少操作次数。

测试样例:

  • 样例1:

    • 输入:S = "aba", T = "abb"
    • 输出:1
    • 解释:将 S 的最后一个字符 'a' 修改为 'b',共需要 1 次操作。
  • 样例2:

    • 输入:S = "abcd", T = "efg"
    • 输出:4
    • 解释:需要对 S 进行 3 次修改(将 'a''b''c' 修改)和 1 次删除,共计 4 次操作。
  • 样例3:

    • 输入:S = "xyz", T = "xy"
    • 输出:1
    • 解释:删除 S 的最后一个字符 'z',共需要 1 次操作。
  • 样例4:

    • 输入:S = "hello", T = "helloworld"
    • 输出:0
    • 解释:S 已经是 T 的前缀,无需任何操作。
  • 样例5:

    • 输入:S = "same", T = "same"
    • 输出:0
    • 解释:S 已经是 T 的前缀,无需任何操作。

为了解决这个问题,我们需要找到将字符串 S 变为 T 的前缀所需的最小操作次数。操作包括:

  1. 修改 S 中的某个字符。
  2. 删除 S 末尾的字符。

我们的目标是最小化修改和删除操作的总次数。

算法思路:

  1. 计算修改次数: 我们需要找到 S 的一个前缀,使其与 T 的前缀匹配。为此,我们可以遍历 S 和 T 的前缀,统计需要修改的字符数量。

  2. 计算删除次数: 对于每个可能的前缀长度 k(从 0 到 min(len(S), len(T))),删除次数就是 S 的长度减去 k。

  3. 总操作次数: 对于每个前缀长度 k,总操作次数等于修改次数加上删除次数。

  4. 寻找最小值: 遍历所有可能的前缀长度,找到最小的总操作次数。

代码实现:

def min_operations(S, T):
    len_s = len(S)
    len_t = len(T)
    min_len = min(len_s, len_t)
    modifications = [0] * (min_len + 1)

    # 计算修改次数
    for i in range(1, min_len + 1):
        if S[i - 1] != T[i - 1]:
            modifications[i] = modifications[i - 1] + 1
        else:
            modifications[i] = modifications[i - 1]

    min_total_cost = float('inf')

    # 计算总操作次数
    for k in range(min_len + 1):
        deletions = len_s - k
        total_cost = modifications[k] + deletions
        min_total_cost = min(min_total_cost, total_cost)

    # 考虑删除所有字符的情况
    if len_s > len_t:
        min_total_cost = min(min_total_cost, len_s)

    return min_total_cost