Given a string S
with only lowercase characters.
Return the number of substrings that contains at least k
distinct characters.
Example 1:
Input: S = "abcabcabca", k = 4
Output: 0
Explanation: There are only three distinct characters in the string.
Example 2:
Input: S = "abcabcabcabc", k = 3
Output: 55
Explanation: Any substring whose length is not smaller than 3 contains a, b, c.
For example, there are 10 substrings whose length are 3, "abc", "bca", "cab" ... "abc"
There are 9 substrings whose length are 4, "abca", "bcab", "cabc" ... "cabc"
...
There is 1 substring whose length is 12, "abcabcabcabc"
So the answer is 1 + 2 + ... + 10 = 55.
至少K个不同字符的子串。
给定一个仅包含小写字母的字符串 S
.
返回 S
中至少包含 k
个不同字符的子串的数量.
注意题目让我们找的是一个满足题意的子串,所以思路可以往滑动窗口上靠拢。但是这道题跟一般滑动窗口题不同的地方在于题目要找的是一个子串至少包含 k 个不同字符。如果是至多的话,我们直接闭上眼睛默写模板即可,但是这里要的是至少,代码就有一些变化,代码大部分还是参照了76题模板。
时间O(n)
空间O(1) - map 几乎可以忽略不计
Java实现
1 public class Solution { 2 public long kDistinctCharacters(String s, int k) { 3 int len = s.length(); 4 // corner case 5 if (len < k) { 6 return 0; 7 } 8 9 // normal case 10 long res = 0; 11 int start = 0; 12 int end = 0; 13 int[] map = new int[256]; 14 // 记录unique的字母个数,类似map.size() 15 int counter = 0; 16 while (end < len) { 17 char c1 = s.charAt(end); 18 if (map[c1] == 0) { 19 counter++; 20 } 21 map[c1]++; 22 end++; 23 while (counter >= k) { 24 // 这是比较巧妙的地方,end所处的位置及其右边直到数组结束,都是满足题意的范围 25 // 都是至少包含了K个不同字符的子串 26 res += len - end + 1; 27 char c2 = s.charAt(start); 28 map[c2]--; 29 if (map[c2] == 0) { 30 counter--; 31 } 32 start++; 33 } 34 } 35 return res; 36 } 37 }