【题目】
给出两个相同长度的由字符a和b构成的字符串,定义它们的距离为对应位置不同的字符的数量。如串“aab”与串“aba”的距离为2;串“ba”与串“aa”的距离为1;串“bba”和串“baa”的距离为0;下面给出两个字符串S与T,其中S的长度不小于T的长度。我们用|S|代表S的长度,|T|代表T的长度,那么S中一共有|S|-|T|+1个与T长度相同的子串,现在你要计算T串与这些|S|-|T|+1个子串的距离的和。
【输入】
第一行包含一个字符串S。
第二行包含一个字符串T。
S和T均有a和b组成,1<=|T|<=|S|<=10^5。
【输出】
输出对应的答案
【样例输入】
aab
aba
【样例输出】
2
我的想法写一个距离函数,然后依次计算距离求和。
#include<iostream>
#include<string>
using namespace std;
int distance(string S, string T)
{
int len = (int)T.length();
int d = 0;
for (int i = 0; i < len; i++)
{
if (S[i] != T[i])
d++;
}
return d;
}
int main()
{
string S;
string T;
/*S = "aaabb";
T = "bab";*/
cin >> S;
cin >> T;
int count = 0;
int n = S.length() - T.length();
if (n == 0)
count = distance(S, T);
else
{
for (int i = 0; i <= n; i++)
count += distance(S.substr(i, T.length()), T);
}
cout << count << endl;
return 0;
}
ac70%超时了,看到牛客群里分享的答案:美团点评2018春招后台开发方向编程题第一题.cpp
分享并记录一下:
上面的比较过程从全局来看,T串从最左边移到了最右边,每移动一次计算一个距离。
对T串的每一个字符来说,都比较了len(S)-len(T)+1次,如果不同结果距离+1,所以问题转化为T串每个字符与S串长度为(len(S)-len(T)+1)子串比较不同个数的总和,比如上面的例子,T[0]与S[0~4]比较,不同个数为1,以此类推,总和为6。
在T串每个字符的比较过程中,也不是遍历的方法比较,只要维护两个变量a,b的个数即可求距离,如果当前T串字符是a,距离肯定等于S(len(S)-len(T)+1)子串中b的个数,如T[0]与S[0~4]比较,S[0~4]中a的个数为4,b的个数为1,T[0]='a',所以T[0]与S[0~4]中每一个b都有一个距离,所以距离为b的个数;如果当前T串字符是b,距离肯定等于S(len(S)-len(T)+1)子串中a的个数。随着T串字符的不同,动态维护a,b的个数即可。
#include<iostream>
#include<string>
using namespace std;
int main()
{
for (string S, T; cin >> S >> T; ) {
int a = 0, b = 0;
int lens = S.size(), lent = T.size();
for (int i = 0; i < lens - lent + 1; i++) //计算a,b个数初始值
a += S[i] == 'a',
b += S[i] == 'b';
int ans = 0;
for (int i = 0; i < lent; i++) {
ans += T[i] == 'a' ? b : a; //T串字符计算距离
S[i] == 'a' ? --a : --b; //维护a,b的数量(去头)
S[i + lens - lent + 1] == 'a' ? ++a : ++b; //维护a,b的数量(加尾)
}
cout << ans << endl;
}
return 0;
}