问题描述
小U和小R有两个字符串,分别是SS和TT,现在小U需要通过对SS进行若干次操作,使其变成TT的一个前缀。操作可以是修改SS的某一个字符,或者删除SS末尾的字符。现在你需要帮助小U计算出,最少需要多少次操作才能让SS变成TT的前缀。
测试样例
样例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 进行最少次数的操作,使得 S 成为 T 的前缀。允许的操作包括:
- 修改
S的某个字符。 - 删除
S的末尾字符。
解题思路
-
前缀匹配:
- 我们需要尽量保留
S的前部分与T相同的部分,称之为公共前缀。 - 如果某个位置的字符不相同,则需要一次修改操作。
- 我们需要尽量保留
-
字符串长度的关系:
- 如果
S的长度比T长,则需要删除多余的字符。 - 如果
S的长度比T短,但公共前缀完全匹配,则不需要额外操作。
- 如果
-
统计操作次数:
-
遍历两个字符串的字符比较:
- 如果
S的当前字符与T的对应字符不同,需要一次修改操作。
- 如果
-
统计公共前缀之后,处理
S剩余部分:- 如果
S的长度大于公共前缀,需要删除多余的字符。
- 如果
-
-
特殊情况:
- 如果
S和T完全相等,则不需要任何操作。 - 如果
S的长度为 0,则需要在前缀处直接修改字符。
- 如果
代码解释
以下代码实现了上述逻辑(java版):
public class Main {
public static int solution(String S, String T) {
int count = 0; // 操作计数器
int lenS = S.length();
int lenT = T.length();
// 遍历 S 和 T 的每个字符
for (int i = 0; i < lenS; i++) {
if (i < lenT) {
// 如果字符不同,累加修改操作
if (S.charAt(i) != T.charAt(i)) {
count++;
}
} else {
// 如果 S 的长度超出 T,需要删除剩余部分
count += lenS - lenT;
break;
}
}
// 返回累积的操作次数
return count;
}
public static void main(String[] args) {
// 测试样例
System.out.println(solution("aba", "abb") == 1); // 修改 1 次
System.out.println(solution("abcd", "efg") == 4); // 修改 3 次 + 删除 1 次
System.out.println(solution("xyz", "xy") == 1); // 删除 1 次
System.out.println(solution("hello", "helloworld") == 0); // 不需要操作
System.out.println(solution("same", "same") == 0); // 不需要操作
}
}
测试用例分析
-
样例 1:
- 输入:
S = "aba", T = "abb" - 公共前缀:
ab - 修改
a -> b,需要 1 次操作。 - 输出:1
- 输入:
-
样例 2:
- 输入:
S = "abcd", T = "efg" - 公共前缀:无。
- 修改 3 次:
a -> e,b -> f,c -> g。 - 删除 1 次:
d。 - 输出:4
- 输入:
-
样例 3:
- 输入:
S = "xyz", T = "xy" - 公共前缀:
xy。 - 删除 1 次:
z。 - 输出:1
- 输入:
-
样例 4:
- 输入:
S = "hello", T = "helloworld" - 公共前缀:
hello。 - 无需修改或删除。
- 输出:0
- 输入:
-
样例 5:
- 输入:
S = "same", T = "same" - 公共前缀:
same。 - 无需修改或删除。
- 输出:0
- 输入:
复杂度分析
- 时间复杂度:
遍历字符串S,复杂度为O(lenS)O(\text{lenS})。 - 空间复杂度:
只使用了常数空间变量,复杂度为O(1)O(1)。
总结
本题的核心在于找到 S 和 T 的最长公共前缀,然后根据两字符串的长度差和字符差异,计算最小的修改和删除次数。