题目地址:
给定一个长 n n n的全是大写英文字母的字符串 s s s,设其某个子串为 t t t, f ( t ) f(t) f(t)为 t t t中只出现 1 1 1次的字母个数,求 ∑ t f ( t ) \sum_t f(t) ∑tf(t), t t t遍历 s s s的所有子串。
我们直接看每个字母对于答案的贡献是多少,即问对于 s [ i ] s[i] s[i],其在多少个子串里是只出现了一次,那么我们就看其最近左边出现的位置和最近右边出现的位置,左右延伸长度的乘积即为其贡献。最后求总和即可。代码如下:
class Solution {
public:
int uniqueLetterString(string s) {
int cur[26], pre[26];
memset(cur, -1, sizeof cur);
memset(pre, -1, sizeof pre);
int res = 0;
for (int i = 0; i < s.size(); i++) {
int idx = s[i] - 'A';
res += (i - cur[idx]) * (cur[idx] - pre[idx]);
pre[idx] = cur[idx];
cur[idx] = i;
}
for (int i = 0; i < 26; i++) res += (s.size() - cur[i]) * (cur[i] - pre[i]);
return res;
}
};
时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)。