小U和小R有两个字符串,分别是S和T,现在小U需要通过对S进行若干次操作,使其变成T的一个前缀。操作可以是修改S的某一个字符,或者删除S末尾的字符。现在你需要帮助小U计算出,最少需要多少次操作才能让S变成T的前缀。
测试样例
样例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
题目链接:www.marscode.cn/practice/8e…
分析
我们需要将字符串 S 转换为字符串 T 的前缀,操作可以是修改 S 中的字符或删除 S 末尾的字符。目标是计算最少操作次数。因为只能删除末尾的字符,所以就不需要用dp了,直接遍历找到不一样的字符替换即可,长度不一样的即代表进行末尾删除操作。
代码逻辑
-
逻辑判断:
- 如果
T的长度m大于或等于S的长度n,则只需要考虑修改操作。 - 如果
T的长度m小于S的长度n,则需要考虑修改操作和删除操作。
- 如果
-
修改操作:
- 在
m >= n的情况下,遍历S和T的相同长度的部分,计算不同字符的数量,并累加到res中。 - 在
m < n的情况下,同样计算不同字符的数量,并累加到res中。
- 在
-
删除操作:
- 在
m < n的情况下,还需要删除S中多余的n - m个字符,因此将n - m累加到res中。
- 在
证明
1. 修改操作的正确性
- 当
m >= n时,S和T的前n个字符需要进行比较。如果S[i] != T[i],则需要一次修改操作。 - 当
m < n时,S和T的前m个字符需要进行比较。如果S[i] != T[i],则需要一次修改操作。
2. 删除操作的正确性
- 当
m < n时,S比T长,需要删除S中多余的n - m个字符,使其长度与T相同。
具体证明
情况1:m >= n
- 在这种情况下,
S和T的前n个字符需要进行比较。 - 如果
S[i] != T[i],则需要一次修改操作。 - 因此,
res累加的是S和T前n个字符中不同字符的数量。
情况2:m < n
- 在这种情况下,
S和T的前m个字符需要进行比较。 - 如果
S[i] != T[i],则需要一次修改操作。 - 此外,
S比T长,需要删除S中多余的n - m个字符。 - 因此,
res累加的是S和T前m个字符中不同字符的数量,再加上n - m次删除操作。
代码如下:
#include <iostream>
#include <string>
using namespace std;
int solution(string S, string T) {
// write code here
int n = S.size(), m = T.size();
int res = 0;
if (m >= n) {
for (int i = 0; i < n; i++) {
res += S[i] != T[i];
}
return res;
}
for (int i = 0; i < m; i++) res += S[i] != T[i];
res += n - m;
return res;
}
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;
}