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

146 阅读2分钟

问题描述

给定两个字符串 𝑆 和 𝑇,我们需要通过以下两种操作之一将 𝑆 变成 𝑇 的前缀:

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

目标是最少的操作次数,使得 𝑆 成为 𝑇 的前缀。

样例分析

  1. 样例1:𝑆="𝑎𝑏𝑎", 𝑇="𝑎𝑏𝑏"

    • 将 𝑆 中的最后一个 'a' 修改为 'b',得到 "abb",此时 𝑆 已经是 𝑇 的前缀。
    • 操作次数:1
  2. 样例2:𝑆="𝑎𝑏𝑐𝑑", 𝑇="𝑒𝑓𝑔"

    • 由于 𝑆 的长度大于 𝑇 的长度,且没有任何字符匹配,需要删除 𝑆 的所有字符。
    • 操作次数:4
  3. 样例3:𝑆="𝑥𝑦𝑧", 𝑇="𝑥𝑦"

    • 删除 𝑆S 的最后一个字符 'z',得到 "xy",此时 𝑆S 已经是 𝑇T 的前缀。
    • 操作次数:1
  4. 样例4:𝑆="ℎ𝑒𝑙𝑙𝑜", 𝑇="ℎ𝑒𝑙𝑙𝑜𝑤𝑜𝑟𝑙𝑑"

    • 𝑆 已经是 𝑇 的前缀,不需要任何操作。
    • 操作次数:0
  5. 样例5:𝑆="𝑠𝑎𝑚𝑒", 𝑇="𝑠𝑎𝑚𝑒"

    • 𝑆 已经是 𝑇 的前缀,不需要任何操作。
    • 操作次数:0

解题步骤

步骤1:初始化变量

  • 初始化操作次数 operations 为 0。
  • 初始化两个指针 i 和 j,分别指向字符串 𝑆 和 𝑇 的起始位置。

步骤2:遍历字符串

  • 使用一个 while 循环,同时遍历字符串 𝑆 和 𝑇。
  • 如果 𝑆[𝑖] 和 𝑇[𝑗] 相同,两个指针都向前移动一位。
  • 如果 𝑆[𝑖] 和 𝑇[𝑗] 不同,增加操作次数 operations 并将两个指针都向前移动一位。

步骤3:处理剩余字符

  • 如果遍历结束后,指针 i 还没有到达 𝑆 的末尾,说明 𝑆 的长度大于 𝑇 的前缀长度,需要删除 𝑆 的末尾字符。
  • 计算需要删除的字符数 len(S) - i,并加到操作次数 operations 上。

步骤4:返回结果

  • 返回操作次数 operations

代码实现

def solution(S: str, T: str) -> int:
# 初始化操作次数
operations = 0
# 初始化两个指针
i, j = 0, 0

# 遍历 S 和 T
while i < len(S) and j < len(T):
    if S[i] == T[j]:
        # 如果字符相同,两个指针都向前移动
        i += 1
        j += 1
    else:
        # 如果字符不同,进行一次修改操作
        operations += 1
        i += 1
        j += 1

# 如果 S 的长度大于 T 的前缀长度,需要删除 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)

总结

时间复杂度

  • 该算法的时间复杂度为 𝑂(min⁡(∣𝑆∣,∣𝑇∣)),其中 ∣𝑆∣ 和 ∣𝑇∣分别是字符串 𝑆 和 𝑇 的长度。这是因为我们最多遍历两个字符串的较短者一次。

空间复杂度

  • 该算法的空间复杂度为 𝑂(1),因为只使用了常数级的额外空间。

关键点

  • 双指针法:使用两个指针分别遍历两个字符串,比较对应字符。
  • 操作计数:在字符不匹配时,增加操作次数。
  • 处理剩余字符:如果 𝑆 的长度大于 𝑇 的前缀长度,需要删除多余字符。