题目
我们定义了一个函数
countUniqueChars(s)
来统计字符串s
中的唯一字符,并返回唯一字符的个数。例如:
s = "LEETCODE"
,则其中"L"
,"T"
,"C"
,"O"
,"D"
都是唯一字符,因为它们只出现一次,所以countUniqueChars(s) = 5
。本题将会给你一个字符串
s
,我们需要返回countUniqueChars(t)
的总和,其中t
是s
的子字符串。输入用例保证返回值为 32 位整数。注意,某些子字符串可能是重复的,但你统计时也必须算上这些重复的子字符串(也就是说,你必须统计
s
的所有子字符串中的唯一字符)。
解题思路
- 按照元素进行统计,如果按照字符串进行统计会导致超时(种类过多);
- 在某个元素出现后,在它第二次出现之前,它保持唯一,这段区间内的数目为:(当前位置 - 上一次出现的位置) * (下一次出现的位置 - 当前位置);
- 对Map进行遍历累加获取结果值。
代码展示
class Solution { public int uniqueLetterString(String s) { int n = s.length(); int ans = 0; //存储数据记录每个元素出现的次数 Map<Character, List<Integer>> data = new HashMap<>(); for (int i = 0; i < n; i++){ List<Integer> temp = data.getOrDefault(s.charAt(i), new ArrayList<>()); temp.add(i); data.put(s.charAt(i), temp); } //对每个元素进行计算,在该元素第二次出现之前,该元素为唯一字符 for (List<Integer> list : data.values()){ int head = -1; int tail = -1; for (int i = 0; i < list.size(); i++){ tail = (i < list.size() - 1) ? list.get(i + 1) : n; ans += (list.get(i) - head) * (tail - list.get(i)); head = list.get(i); } } return ans; } }