刷题实践| 豆包MarsCode AI 刷题

55 阅读4分钟

解题思路与代码实现

问题描述

小U和小R有两个字符串,分别是 ST。小U需要通过对 S 进行若干次操作,使其变成 T 的一个前缀。操作可以是:

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

请帮助小U计算出,最少需要多少次操作才能让 S 变成 T 的前缀。如果无法按照要求选择菜品,则输出 -1

测试样例

  • 样例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 的前缀,需要确保转换后的 ST 的开头部分。具体步骤如下:

  1. 确定公共前缀长度:

    • 查找 ST 之间的最长公共前缀长度 commonLength
    • commonLength 是从左到右,ST 第一个不同字符之前的相同字符数。
  2. 计算需要的修改次数:

    • 删除操作:
      • 如果 S 的长度大于 commonLength,需要删除 S 末尾的字符,次数为 S.length() - commonLength
    • 修改操作:
      • 如果 S 的长度小于或等于 T 的长度,且 S 的前 commonLength 个字符与 T 的前 commonLength 个字符相同,需要将 S 的末尾部分修改为 T 的对应部分。
      • 修改次数为 S 的长度减去 commonLength,即 min(S.length(), T.length()) - commonLength
  3. 特殊情况处理:

    • 如果 S 的长度超过 T 的长度,并且 T 不是 S 的前缀,则需要删除额外的字符。
    • 如果 S 的公共前缀部分不匹配 T,则可能无法通过修改和删除操作使 S 成为 T 的前缀,需要输出 -1
  4. 总结操作步骤:

    • 总操作次数为删除操作次数加修改操作次数。
    • 如果无法满足条件,则返回 -1

代码实现

以下是根据上述思路编写的Java代码:

代码说明

  1. 找到最长公共前缀 (commonLength):

    • 使用 while 循环,逐个比较 ST 的字符,直到找到第一个不同的字符。
    • commonLength 记录了 ST 共有的前缀长度。
  2. 判断是否需要删除操作:

    • 如果 S 的长度大于 commonLength,则需要删除多余的字符。
    • 删除次数为 sLen - commonLength
  3. 判断是否需要修改操作:

    • 如果 S 的长度小于 T 的长度,且 S 还有未匹配的部分,需要进行修改。
    • 修改次数为 min(S.length(), T.length()) - commonLength
  4. 计算总操作次数:

    • 总操作次数为删除操作次数加上修改操作次数。
  5. 返回结果:

    • 根据以上操作,返回总操作次数。
    • 在这题中,由于删除和修改操作在逻辑上已经确保了 S 可以成为 T 的前缀,因此无需额外验证,直接返回 totalOps

测试样例验证

  1. 样例1:

    • 输入: S = "aba", T = "abb"
    • 最长公共前缀: "ab"commonLength = 2
    • 删除次数: 3 - 2 = 1
    • 修改次数: 0(因为 S.length() < T.length(),无需修改)
    • 总操作次数: 1 + 0 = 1
    • 输出: 1
  2. 样例2:

    • 输入: S = "abcd", T = "efg"
    • 最长公共前缀: ""commonLength = 0
    • 删除次数: 4 - 0 = 4
    • 修改次数: 0(因为 S.length() > T.length(),无需修改)
    • 总操作次数: 4 + 0 = 4
    • 输出: 4
  3. 样例3:

    • 输入: S = "xyz", T = "xy"
    • 最长公共前缀: "xy"commonLength = 2
    • 删除次数: 3 - 2 = 1
    • 修改次数: 0(因为 S.length() > T.length(),无需修改)
    • 总操作次数: 1 + 0 = 1
    • 输出: 1
  4. 样例4:

    • 输入: S = "hello", T = "helloworld"
    • 最长公共前缀: "hello"commonLength = 5
    • 删除次数: 5 - 5 = 0
    • 修改次数: 0(因为 S.length() < T.length(),无需修改)
    • 总操作次数: 0 + 0 = 0
    • 输出: 0
  5. 样例5:

    • 输入: S = "same", T = "same"
    • 最长公共前缀: "same"commonLength = 4
    • 删除次数: 4 - 4 = 0
    • 修改次数: 0(因为 S.length() == T.length(),且无需修改)
    • 总操作次数: 0 + 0 = 0
    • 输出: 0

结论

通过上述方法,我们能够有效地计算出将字符串 S 转换为 T 的前缀所需的最少操作次数。算法的时间复杂度为 O(n),其中 n 是字符串 S 的长度,适用于大多数实际情况。