解题思路与代码实现
问题描述
小U和小R有两个字符串,分别是 S 和 T。小U需要通过对 S 进行若干次操作,使其变成 T 的一个前缀。操作可以是:
- 修改 S 的某一个字符。
- 删除 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 的前缀,需要确保转换后的 S 是 T 的开头部分。具体步骤如下:
-
确定公共前缀长度:
- 查找 S 和 T 之间的最长公共前缀长度
commonLength。 commonLength是从左到右,S 和 T 第一个不同字符之前的相同字符数。
- 查找 S 和 T 之间的最长公共前缀长度
-
计算需要的修改次数:
- 删除操作:
- 如果 S 的长度大于
commonLength,需要删除 S 末尾的字符,次数为S.length() - commonLength。
- 如果 S 的长度大于
- 修改操作:
- 如果 S 的长度小于或等于 T 的长度,且 S 的前
commonLength个字符与 T 的前commonLength个字符相同,需要将 S 的末尾部分修改为 T 的对应部分。 - 修改次数为 S 的长度减去
commonLength,即min(S.length(), T.length()) - commonLength。
- 如果 S 的长度小于或等于 T 的长度,且 S 的前
- 删除操作:
-
特殊情况处理:
- 如果 S 的长度超过 T 的长度,并且 T 不是 S 的前缀,则需要删除额外的字符。
- 如果 S 的公共前缀部分不匹配 T,则可能无法通过修改和删除操作使 S 成为 T 的前缀,需要输出
-1。
-
总结操作步骤:
- 总操作次数为删除操作次数加修改操作次数。
- 如果无法满足条件,则返回
-1。
代码实现
以下是根据上述思路编写的Java代码:
代码说明
-
找到最长公共前缀 (
commonLength):- 使用
while循环,逐个比较 S 和 T 的字符,直到找到第一个不同的字符。 commonLength记录了 S 和 T 共有的前缀长度。
- 使用
-
判断是否需要删除操作:
- 如果 S 的长度大于
commonLength,则需要删除多余的字符。 - 删除次数为
sLen - commonLength。
- 如果 S 的长度大于
-
判断是否需要修改操作:
- 如果 S 的长度小于 T 的长度,且 S 还有未匹配的部分,需要进行修改。
- 修改次数为
min(S.length(), T.length()) - commonLength。
-
计算总操作次数:
- 总操作次数为删除操作次数加上修改操作次数。
-
返回结果:
- 根据以上操作,返回总操作次数。
- 在这题中,由于删除和修改操作在逻辑上已经确保了 S 可以成为 T 的前缀,因此无需额外验证,直接返回
totalOps。
测试样例验证
-
样例1:
- 输入:
S = "aba",T = "abb" - 最长公共前缀:
"ab",commonLength = 2 - 删除次数:
3 - 2 = 1 - 修改次数:
0(因为S.length() < T.length(),无需修改) - 总操作次数:
1 + 0 = 1 - 输出:
1
- 输入:
-
样例2:
- 输入:
S = "abcd",T = "efg" - 最长公共前缀:
"",commonLength = 0 - 删除次数:
4 - 0 = 4 - 修改次数:
0(因为S.length() > T.length(),无需修改) - 总操作次数:
4 + 0 = 4 - 输出:
4
- 输入:
-
样例3:
- 输入:
S = "xyz",T = "xy" - 最长公共前缀:
"xy",commonLength = 2 - 删除次数:
3 - 2 = 1 - 修改次数:
0(因为S.length() > T.length(),无需修改) - 总操作次数:
1 + 0 = 1 - 输出:
1
- 输入:
-
样例4:
- 输入:
S = "hello",T = "helloworld" - 最长公共前缀:
"hello",commonLength = 5 - 删除次数:
5 - 5 = 0 - 修改次数:
0(因为S.length() < T.length(),无需修改) - 总操作次数:
0 + 0 = 0 - 输出:
0
- 输入:
-
样例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 的长度,适用于大多数实际情况。