题意简述
小U和小R拥有两个字符串,分别为 S 和 T。小U的任务是通过对字符串 S 进行一系列操作,使得 S 最终成为 T 的一个前缀。允许的操作包括:
- 修改
S中的任意字符。 - 删除
S末尾的字符。
我们的目标是计算出将 S 转变为 T 的前缀所需的最少操作次数。
思路分析
长度比较
-
当
|S| > |T|:- 如果字符串
S的长度大于字符串T,那么必须首先通过删除S尾部的字符来匹配T的长度。具体来说,需要删除|S| - |T|个字符。 - 例如,若
S = "abcde",T = "abc",则需要删除最后两个字符d和e,使得S的长度减小到与T相同。
- 如果字符串
-
当
|S| ≤ |T|:- 若字符串
S的长度小于或等于T,则我们需要将S的字符逐个与T的对应字符进行比较。 - 在这个过程中,统计
S中与T对应位置字符不同的数量,即可得到需要修改的字符数量。这种情况下的最优操作策略是只进行必要的修改。
- 若字符串
具体操作
-
删除操作:对于
|S| > |T|的情况,我们需要进行|S| - |T|次删除操作来调整S的长度。 -
修改操作:若
|S| ≤ |T|,则遍历S中的字符与T进行比较。对于每一个不同的字符,增加一项修改操作的计数。具体步骤如下:- 遍历
S(从0到|S| - 1)与T(从0到|S| - 1)进行字符的比对。 - 计算
S[i]和T[i]是否相同,若不同则计数器加1。
- 遍历
最终操作数计算
-
综合两种情况,最终的操作次数可以表示为:
- 如果
|S| > |T|: - 如果
|S| \leq |T|:
- 如果
示例分析
考虑以下例子:
-
输入:
S = "abcdef",T = "abc"- 由于
|S| > |T|,需要删除后3个字符d,e,f,因此需进行3次删除操作。此时S变为"abc",无需修改。 - 总操作数:3。
- 由于
-
输入:
S = "abcd",T = "abcde"- 由于
|S| < |T|,需要修改的字符数为0(因为长度不足,不存在可以修改的字符),可以视为S的后续字符可直接加。无性质修改操作。 - 此时,只需附加一个字符
e,但是并不在操作计算中。 - 总操作数:1(可以理解为追加而非修改)。
- 由于
通过上述分析,可以很好地得出所需的操作步数。这种思路清晰地揭示了如何通过删除和修改两种基本操作,逐步将 S 变为 T 的前缀,体现了问题的合理性与步骤的有效性。
代码实现
#include <iostream>
#include <string>
using namespace std;
int solution(string S, string T) {
// write code here
int ls, lt;
ls = S.size();
lt = T.size();
int ans = max(0, ls - lt);
for (int i = min(ls, lt) - 1; i >= 0; i--) {
ans += S[i] != T[i];
}
return ans;
}
int main() {
cout << (solution("aba", "abb") == 1) << endl;
cout << (solution("abcd", "efg") == 4) << endl;
cout << (solution("xyz", "xy") == 1) << endl;
cout << (solution("hello", "helloworld") == 0) << endl;
cout << (solution("same", "same") == 0) << endl;
return 0;
}