📌  相关文章
📜  计算至少有 K 个不同字符的子串的数量(1)

📅  最后修改于: 2023-12-03 15:41:41.706000             🧑  作者: Mango

计算至少有 K 个不同字符的子串的数量

在字符串处理中,有些场景需要计算至少有 K 个不同字符的子串的数量,比如搜索引擎中的关键词匹配。下面介绍几种方法来实现这个功能。

方法一:暴力枚举

最简单的方法就是暴力枚举,对于每个子串,统计其中不同字符的个数,如果不同字符的个数大于等于 K,就将计数器加一。时间复杂度为 O(n^3)。

def sub_string_count(s: str, K: int) -> int:
    n = len(s)
    cnt = 0
    for i in range(n):
        for j in range(i + 1, n + 1):
            sub_str = s[i:j]
            if len(set(sub_str)) >= K:
                cnt += 1
    return cnt
方法二:滑动窗口

我们可以通过滑动窗口来优化时间复杂度。维护一个滑动窗口,保证窗口中的不同字符个数大于等于 K。对于每个右端点,计算以该右端点为结尾的子串数量,加上这些子串的数量即可。时间复杂度为 O(n^2)。

def sub_string_count(s: str, K: int) -> int:
    n = len(s)
    cnt = 0
    for i in range(n):
        j = i
        window = set()
        while j < n:
            window.add(s[j])
            if len(window) >= K:
                cnt += n - j
                break
            j += 1
    return cnt
方法三:双指针

我们可以维护一个左指针和一个右指针,指向当前窗口的左右端点。初始化时,左右指针都指向字符串的起始位置。然后我们先向右移动右指针,直到包含 K 个不同字符为止。此时,以右指针为右端点的子串数量即为字符串长度减去右指针位置。接下来,每次向右移动左指针,直到不再包含 K 个不同字符为止。每次移动时,以左指针为左端点的子串数量即为右指针位置减去左指针位置。时间复杂度为 O(n)。

def sub_string_count(s: str, K: int) -> int:
    n = len(s)
    cnt = 0
    left, right = 0, 0
    window = set()
    while right < n:
        window.add(s[right])
        if len(window) >= K:
            cnt += n - right
            break
        right += 1
    while left < right:
        window.remove(s[left])
        left += 1
        while right < n:
            window.add(s[right])
            if len(window) >= K:
                cnt += n - right
                break
            right += 1
    return cnt

以上就是三种计算至少有 K 个不同字符的子串数量的方法,可以根据具体情况选择相应的方法进行实现。