暴力解1:(只能获得百分之五十的分数)
#include<bits/stdc++.h>
using namespace std;
int hashA[27];
string s;
int uniqueC(int l,int r) {
int ans=0;
for(int i=l; i<=r; i++)
hashA[s[i]-'a']++;
for(int i=0; i<26; i++) {
if(hashA[i]==1)
ans++;
}
memset(hashA,0,sizeof(hashA));
return ans;
}
void QuerySubstr() {
int ans=0;
for(int i=0; i<s.size(); i++) {
for(int j=i; j<s.size(); j++)
ans+=uniqueC(i,j);
}
cout<<ans<<endl;
}
int main(void) {
cin>>s;
QuerySubstr();
return 0;
}
最后会运行超时。
其他思路:
看了别人的一个思路,就是每个字母的贡献度。但是他们写的代码都太复杂我没看懂,我就自己想了想,然后提交过了,仅供大家参考。
解题思路
首先遍历字符串每一个字母,去找每个字母的贡献度。
- 当遍历到s[i]时候,我们去找它左边界和右边界,那么这个边界是什么呢?就是在它左边与它相等的下标的下一个,在它右边与它相等的下标的前一个。
- 然后问题就转换成了,一个区间[L,R],区间内存在一个数x,算出包含x的所有字串。
- 这个问题又有的想了,但是也比较简单。 先是只包含x左边的字串,有n1个 只包含x右边的字串,有n2个 两边都有的是n1*n2个,这个大家可以画图理解理解,就是一个组合的问题。
- 下面就是代码了:
#include <bits/stdc++.h> using namespace std; string s; int main(void) { int ans = 0; cin >> s; for (int i = 0; i < s.size(); i++) { int left = i - 1, right = i + 1; while (left >= 0 && s[left] != s[i]) left--; while (right < s.size() && s[right] != s[i]) right++; left++; right--; ans += (i - left) + (right - i) + (i - left) * (right - i); } cout << ans+s.size() << endl; //system("pause"); return 0; }