1375. 至少K个不同字符的子串
给定一个仅包含小写字母的字符串 S.
返回 S 中至少包含 k 个不同字符的子串的数量.
样例
样例 1:
输入: S = "abcabcabca", k = 4
输出: 0
解释: 字符串中一共就只有 3 个不同的字符.
样例 2:
输入: S = "abcabcabcabc", k = 3
输出: 55
解释: 任意长度不小于 3 的子串都含有 a, b, c 这三个字符.
比如,长度为 3 的子串共有 10 个, "abc", "bca", "cab" ... "abc"
长度为 4 的子串共有 9 个, "abca", "bcab", "cabc" ... "cabc"
...
长度为 12 的子串有 1 个, 就是 S 本身.
所以答案是 1 + 2 + ... + 10 = 55.
注意事项
-
10 ≤ length(S) ≤ 1,000,000
-
1 ≤ k ≤ 26
public class Solution {
/**
* @param s: a string
* @param k: an integer
* @return: the number of substrings there are that contain at least k distinct characters
*/
public long kDistinctCharacters(String s, int k) {
int[] map = new int[126];
int size = 0;
long sum = 0;
int i = 0;
int len = s.length();
for (; i < len; i++) {
int c = s.charAt(i);
if (map[c] == 0) {
size++;
if (size == k) {
sum += len - i;
map[c]++;
break;
}
}
map[c]++;
}
for (int j = 0; j < len; j++) {
int c = s.charAt(j);
map[c]--;
if (map[c] > 0) {
sum += len - i;
} else {
size--;
for (i++; i < len; i++) {
c = s.charAt(i);
if (map[c] == 0) {
size++;
if (size == k) {
sum += len - i;
map[c]++;
break;
}
}
map[c]++;
}
if (i == len) {
break;
}
}
}
return sum;
}
}
public class Solution {
/**
* @param s: a string
* @param k: an integer
* @return: the number of substrings there are that contain at least k distinct characters
*/
public long kDistinctCharacters(String s, int k) {
HashMap<Character, Integer> map = new HashMap<>(26);
long sum = 0;
int i = 0;
for (; i < s.length(); i++) {
char c = s.charAt(i);
if (map.containsKey(c)) {
int num = map.get(c);
num++;
map.put(c, num);
} else {
map.put(c, 1);
if (map.size() == k) {
sum += s.length() - i;
break;
}
}
}
for (int j = 0; j < s.length(); j++) {
char c = s.charAt(j);
int num = map.get(c);
num--;
if (num > 0) {
sum += s.length() - i;
map.put(c, num);
} else {
map.remove(c);
boolean has=true;
for (i++; i < s.length(); i++) {
c = s.charAt(i);
if (map.containsKey(c)) {
int size = map.get(c);
size++;
map.put(c, size);
} else {
map.put(c, 1);
if (map.size() == k) {
sum += s.length() - i;
has=false;
break;
}
}
}
if (has){
break;
}
}
}
return sum;
}
}