Keshawn_lu's Blog

Leetcode 828. 统计子串中的唯一字符

字数统计: 562阅读时长: 2 min
2022/09/06 Share

题目简介:

我们定义了一个函数 countUniqueChars(s) 来统计字符串 s 中的唯一字符,并返回唯一字符的个数。

例如:s = "LEETCODE" ,则其中 "L", "T","C","O","D" 都是唯一字符,因为它们只出现一次,所以 countUniqueChars(s) = 5

本题将会给你一个字符串 s ,我们需要返回 countUniqueChars(t) 的总和,其中 ts 的子字符串。输入用例保证返回值为 32 位整数。

注意,某些子字符串可能是重复的,但你统计时也必须算上这些重复的子字符串(也就是说,你必须统计 s 的所有子字符串中的唯一字符)。

示例 1:

1
2
3
4
5
输入: s = "ABC"
输出: 10
解释: 所有可能的子串为:"A","B","C","AB","BC" 和 "ABC"。
其中,每一个子串都由独特字符构成。
所以其长度总和为:1 + 1 + 1 + 2 + 2 + 3 = 10

提示:

  • 1 <= s.length <= 10^5
  • s 只包含大写英文字符

思路:

由于是记录唯一字符出现的次数,所以我们只需对每个字符,计算有多少子字符串仅包含该字符一次即可。

例如s = BABCAD, 若当前字符为s[1] = A

我们以1这个索引为分界线,1左边的字符串可以分解为BA, A

1之后到s[4] = A之间的字符串,可以分解为空串, B, BC

因此,字符串两两组合,一共有2 * 3 = 6种情况。(BA, A, BAB, AB, BABC, ABC

所以,设当前字符的索引为i, 同字符上一次出现的位置为 last(没有则为-1),下一次为next(没有则为s.size()),则该字符的贡献量为(last - i) * (next - i)

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution {
public:
int uniqueLetterString(string s) {

unordered_map<char, vector<int>> map;

for(int i = 0; i < s.size(); i++){

map[s[i]].push_back(i); //记录相同字符的位置
}


int res = 0;
for(auto& item : map){

auto arr = item.second;

arr.insert(arr.begin(), -1); //开头插入
arr.push_back(s.size()); //结尾插入

for(int i = 1; i < arr.size() - 1; i++)
res += (arr[i] - arr[i - 1]) * (arr[i + 1] - arr[i]);
}

return res;
}
};
CATALOG
  1. 1. 题目简介:
  2. 2. 思路:
  3. 3. 代码如下: