力扣题目链接:https://leetcode.cn/problems/count-unique-characters-of-all-substrings-of-a-given-string/
我们定义了一个函数 countUniqueChars(s)
来统计字符串 s
中的唯一字符,并返回唯一字符的个数。
例如:s = "LEETCODE"
,则其中 "L"
, "T"
,"C"
,"O"
,"D"
都是唯一字符,因为它们只出现一次,所以 countUniqueChars(s) = 5
。
本题将会给你一个字符串 s
,我们需要返回 countUniqueChars(t)
的总和,其中 t
是 s
的子字符串。注意,某些子字符串可能是重复的,但你统计时也必须算上这些重复的子字符串(也就是说,你必须统计 s
的所有子字符串中的唯一字符)。
由于答案可能非常大,请将结果 mod 10 ^ 9 + 7 后再返回。
示例 1:
输入: s = "ABC" 输出: 10 解释: 所有可能的子串为:"A","B","C","AB","BC" 和 "ABC"。 其中,每一个子串都由独特字符构成。 所以其长度总和为:1 + 1 + 1 + 2 + 2 + 3 = 10
示例 2:
输入: s = "ABA"
输出: 8
解释: 除了 countUniqueChars
("ABA") = 1 之外,其余与示例 1 相同。
示例 3:
输入:s = "LEETCODE" 输出:92
提示:
0 <= s.length <= 10^5
s
只包含大写英文字符每个字符之间互不影响,因此我们分别统计每个字母即可。
对于某个字母,要找到包含这个字母一次有且仅有一次的字符串,可以从某个“这个字母出现的位置”开始,左边选数个字母(不包含这个字母)、右边选数个字母。
因此,如果字母 X X X的三个相邻的出现位置分别是 i i i、 j j j和 k k k,那么包含 s [ j ] s[j] s[j]一次的字符串种类有 ( j − i ) × ( k − j ) (j-i)\times(k-j) (j−i)×(k−j)个。
因此,预处理一遍,统计每个字母出现的位置,再进行上述运算即可。
class Solution {
public:
int uniqueLetterString(string& s) {
int n = s.size();
vector<int> location[26];
for (int i = 0; i < 26; i++) {
location[i].push_back(-1);
}
for (int i = 0; i < n; i++) {
location[s[i] - 'A'].push_back(i);
}
for (int i = 0; i < 26; i++) {
location[i].push_back(n);
}
int ans = 0;
for (int i = 0; i < 26; i++) {
if (location[i].size() == 2)
continue;
for (int j = 1; j + 1 < location[i].size(); j++) {
ans += (location[i][j] - location[i][j - 1]) * (location[i][j + 1] - location[i][j]);
}
}
return ans;
}
};
同步发文于CSDN,原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/126722643