comments | difficulty | edit_url | rating | source | tags | |||
---|---|---|---|---|---|---|---|---|
true |
中等 |
1454 |
第 420 场周赛 Q2 |
|
给你一个字符串 s
和一个整数 k
,在 s
的所有子字符串中,请你统计并返回 至少有一个 字符 至少出现 k
次的子字符串总数。
子字符串 是字符串中的一个连续、 非空 的字符序列。
示例 1:
输入: s = "abacb", k = 2
输出: 4
解释:
符合条件的子字符串如下:
"aba"
(字符'a'
出现 2 次)。"abac"
(字符'a'
出现 2 次)。"abacb"
(字符'a'
出现 2 次)。"bacb"
(字符'b'
出现 2 次)。
示例 2:
输入: s = "abcde", k = 1
输出: 15
解释:
所有子字符串都有效,因为每个字符至少出现一次。
提示:
1 <= s.length <= 3000
1 <= k <= s.length
s
仅由小写英文字母组成。
我们可以枚举子字符串的右端点,然后用一个滑动窗口维护子字符串的左端点,使得滑动窗口内的子字符串中的每个字符出现次数都小于
我们可以用一个数组
当我们枚举右端点时,我们可以将右端点的字符加入滑动窗口,然后判断滑动窗口内右端点的字符出现次数是否大于等于
枚举结束后,返回答案即可。
时间复杂度
class Solution:
def numberOfSubstrings(self, s: str, k: int) -> int:
cnt = Counter()
ans = l = 0
for c in s:
cnt[c] += 1
while cnt[c] >= k:
cnt[s[l]] -= 1
l += 1
ans += l
return ans
class Solution {
public int numberOfSubstrings(String s, int k) {
int[] cnt = new int[26];
int ans = 0, l = 0;
for (int r = 0; r < s.length(); ++r) {
int c = s.charAt(r) - 'a';
++cnt[c];
while (cnt[c] >= k) {
--cnt[s.charAt(l) - 'a'];
l++;
}
ans += l;
}
return ans;
}
}
class Solution {
public:
int numberOfSubstrings(string s, int k) {
int n = s.size();
int ans = 0, l = 0;
int cnt[26]{};
for (char& c : s) {
++cnt[c - 'a'];
while (cnt[c - 'a'] >= k) {
--cnt[s[l++] - 'a'];
}
ans += l;
}
return ans;
}
};
func numberOfSubstrings(s string, k int) (ans int) {
l := 0
cnt := [26]int{}
for _, c := range s {
cnt[c-'a']++
for cnt[c-'a'] >= k {
cnt[s[l]-'a']--
l++
}
ans += l
}
return
}
function numberOfSubstrings(s: string, k: number): number {
let [ans, l] = [0, 0];
const cnt: number[] = Array(26).fill(0);
for (const c of s) {
const x = c.charCodeAt(0) - 'a'.charCodeAt(0);
++cnt[x];
while (cnt[x] >= k) {
--cnt[s[l++].charCodeAt(0) - 'a'.charCodeAt(0)];
}
ans += l;
}
return ans;
}