Leetcode 828. 统计子串中的唯一字符
题目
我们定义了一个函数 countUniqueChars(s) 来统计字符串 s 中的唯一字符,并返回唯一字符的个数。
例如:s = “LEETCODE” ,则其中 “L”, “T”,“C”,“O”,“D” 都是唯一字符,因为它们只出现一次,所以 countUniqueChars(s) = 5 。
本题将会给你一个字符串 s ,我们需要返回 countUniqueChars(t) 的总和,其中 t 是 s 的子字符串。注意,某些子字符串可能是重复的,但你统计时也必须算上这些重复的子字符串(也就是说,你必须统计 s 的所有子字符串中的唯一字符)。
由于答案可能非常大,请将结果 mod 10 ^ 9 + 7 后再返回。
测试样例
示例 1:
输入: "ABC"
输出: 10
解释: 所有可能的子串为:"A","B","C","AB","BC" 和 "ABC"。
其中,每一个子串都由独特字符构成。
所以其长度总和为:1 + 1 + 1 + 2 + 2 + 3 = 10
示例 2:
输入: "ABA"
输出: 8
解释: 除了 countUniqueChars("ABA") = 1 之外,其余与示例 1 相同。
示例 3:
输入:s = "LEETCODE"
输出:92
提示:
- 0 <= s.length <= 10^4
- s 只包含大写英文字符
题解
我们对每个字母分别计数
对于字符c,我们仅计算包含c一次的子串个数,假设s[i]=c,我们尽可能的向右、左找不含c的最长范围,假设[left+1,right-1]中只含一个c,那么对于c的贡献度为1的子串就有(i-left)*(right-i)个。我们对每个字符进行这种操作便可以获得答案。
详细过程见代码
代码
int uniqueLetterString(string s) {
int n=s.length(),mod=pow(10,9)+7;
int left,right,ans=0;
for(int i=0; i<n; i++){
left=i-1;
right=i+1;
while(left>=0 && s[left]!=s[i]) left--; //向左找,找最大范围
while(right<n && s[right]!=s[i]) right++; //向右找,找最大范围
ans += (i-left)*(right-i)%mod; //s[i]共献1个的子串共有(i-left)*(right-i)个
}
return ans;
}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-unique-characters-of-all-substrings-of-a-given-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。