写法2:枚举
分析:
不能陷入找子串的思维中,不然时间复杂度就是$O(n ^ 2)$的量级,考虑每个字母对子串的贡献。
#include <iostream>
#include <vector>
using namespace std;
vector<int> pos[26];
int main()
{
string s;
cin >> s;
s = "0" + s; // 下标从0开始
int n = s.size();
for(int i = 0;i < 26;i ++ ) pos[i].push_back(0); // 处理边界
for(int i = 1;i <= n - 1;i ++ ) {
pos[s[i] - 'a'].push_back(i);
}
for(int i = 0;i < 26;i ++ ) pos[i].push_back(n); // 处理边界
long long res = 0;
for(int i = 0;i < 26;i ++ ){
auto c = pos[i];
if(c.size() == 2) continue; // 字母没出现过
for(int i = 1;i < c.size() - 1;i ++ ){
res += (long long)(c[i] - c[i - 1]) * (c[i + 1] - c[i]);
}
}
cout << res << endl;
return 0;
}
写法1,我踏马直接暴力,50分代码
#include <iostream>
#include <cstring>
using namespace std;
const int N = 100010;
int cnt[26];
int main()
{
string s;
cin >> s;
long long res = 0;
for(int i = 0;i < s.size();i ++ )
for(int j = 0;j <= i;j ++ )
{
int sc = 0;
memset(cnt,0,sizeof cnt);
for(int k = j;k <= i;k ++ ) cnt[s[k] - 'a'] ++ ;
for(int k = 0;k < 26;k ++ ){
if(cnt[k] == 1) sc ++;
}
res += sc;
}
cout << res <<endl;
return 0;
}