Count Unique Characters of All Substrings of a Given String

Count Unique Characters of All Substrings of a Given String

Let's define a function countUniqueChars(s) that returns the number of unique characters on s .

  • For example, calling countUniqueChars(s) if s = "LEETCODE" then "L" , "T" , "C" , "O" , "D" are the unique characters since they appear only once in s , therefore countUniqueChars(s) = 5 .

Given a string s , return the sum of countUniqueChars(t) where t is a substring of s . The test cases are generated such that the answer fits in a 32-bit integer.

Notice that some substrings can be repeated so in this case you have to count the repeated ones too.

Example 1:

Input: s = "ABC"
Output: 10
Explanation: All possible substrings are: "A","B","C","AB","BC" and "ABC".
Every substring is composed with only unique letters.
Sum of lengths of all substring is 1 + 1 + 1 + 2 + 2 + 3 = 10

Example 2:

Input: s = "ABA"
Output: 8
Explanation: The same as example 1, except countUniqueChars("ABA") = 1.

Example 3:

Input: s = "LEETCODE"
Output: 92

Constraints:

1s.length105
 s consists of uppercase English letters only.

 

解题思路

  这题思路没想到。容易想到的思路是枚举出每一个子串,然后对每一个子串统计各个字符出现的次数,但这样做明显会超时。关键是要想到,对于某一个字符,它只有在子串中仅出现一次时,该字符才对子串有贡献。

  因此现在的思路是,对于每个字符,看看有多少个子串是满足该字符在子串中仅出现一次。假设这个字符当前所在的位置为ci,同类型字符上一次出现的位置在cj,下一次出现的位置在ck。那么对于ci这个字符来说,有(cicj)×(ckci)个子串是满足该字符在子串中仅出现一次。首先子串肯定是包含ci这个位置的字符,不包含cjck这两个位置的字符。然后在子串的前半部分即(cj,ci],有cicj种选法,后半部分即[ci,ck),有ckci种选法,根据乘法原理一共有(cicj)×(ckci)种选法。

  因此做法是扫描一遍字符串,存储各个字符出现的位置,然后再枚举每个字符,用上面的公式来累计答案。需要注意的一点是对于每个字符都需要在最前面加入1这个下标位置和在最后加入n这个下标位置(n是字符串长度,下标从0开始)。

  AC代码如下:

复制代码
 1 class Solution {
 2 public:
 3     int uniqueLetterString(string s) {
 4         vector<int> mp[26];
 5         for (int i = 0; i < s.size(); i++) {
 6             mp[s[i] - 'A'].push_back(i);
 7         }
 8         int ret = 0;
 9         for (int i = 0; i < 26; i++) {
10             mp[i].insert(mp[i].begin(), -1);
11             mp[i].push_back(s.size());
12             for (int j = 1; j < mp[i].size() - 1; j++) {
13                 ret += (mp[i][j] - mp[i][j - 1]) * (mp[i][j + 1] - mp[i][j]);
14             }
15         }
16         return ret;
17     }
18 };
复制代码

 

参考资料  

  统计子串中的唯一字符:https://leetcode.cn/problems/count-unique-characters-of-all-substrings-of-a-given-string/solution/tong-ji-zi-chuan-zhong-de-wei-yi-zi-fu-b-h9pj/

posted @   onlyblues  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示