📅  最后修改于: 2023-12-03 15:12:02.631000             🧑  作者: Mango
给定一个字符串和一个整数K,求出所有的子串中,字符权重之和不超过K的子串个数。
字符权重指的是字符在字符串中出现的次数。
例如,对于字符串"aaabbc",其子串"aa"的字符权重为2,子串"ab"的字符权重为1。
我们可以枚举所有的子串,然后计算其字符权重,并统计所有符合条件的子串的数量。
对于计算字符权重,我们可以使用一个map来保存每个字符出现的次数,然后累加每个字符的出现次数即可。
我们可以通过滑动窗口来遍历所有的子串,并在遍历的过程中,动态地更新累计的字符权重信息。
具体来说,我们可以使用两个指针left和right,分别表示当前滑动窗口的左右边界。我们从左向右遍历字符串,并移动right指针,每次将right指向的字符的出现次数加1,然后更新当前滑动窗口中的字符权重。
如果当前字符权重超过了K,那么我们就需要移动left指针,同时将left指向的字符的出现次数减1。这样可以保证滑动窗口中的字符权重和不超过K。
当我们移动left指针时,有一个特殊情况需要注意,即如果当前left指针指向的字符在滑动窗口中已经不存在了,那么我们就需要从map中将其删除。
具体实现可以参考下面的代码片段。
def count_substrings(s: str, k: int) -> int:
n = len(s)
cnt = {}
left, right = 0, 0
res = 0
while right < n:
# move right pointer and update character count
cnt[s[right]] = cnt.get(s[right], 0) + 1
# update substring weight
weight = sum(cnt.values())
# move left pointer if weight is too big
while weight > k and left <= right:
cnt[s[left]] -= 1
if cnt[s[left]] == 0:
del cnt[s[left]]
left += 1
weight = sum(cnt.values())
# count valid substrings ending with s[right]
if weight <= k:
res += right - left + 1
right += 1
return res
时间复杂度:$O(n^2)$
空间复杂度:$O(n)$
其中n为字符串s的长度。