📌  相关文章
📜  具有恰好 K 个不同字符的最小长度子串(1)

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

具有恰好 K 个不同字符的最小长度子串

当需要在字符串中找到恰好包含K个不同字符的最小长度子串时,可以使用滑动窗口算法来解决此问题。

滑动窗口算法的基本思想是维护一个窗口,窗口大小在不断地变化着以满足问题的要求。在这个问题中,我们可以左右指针分别指向子串的左右两端,然后移动右指针,一旦当前窗口中包含恰好K个不同字符,我们就可以移动左指针,缩小子串的长度。在整个过程中,我们不断地更新答案,最终得到的就是包含恰好K个不同字符的最小长度子串。

以下是基于Python的滑动窗口算法的实现:

def k_distinct_substring(s: str, k: int) -> str:
    if k <= 0:
        return ""
    if k >= len(s):
        return s

    left, right = 0, 0
    distinct_count = 0
    char_counts = defaultdict(lambda: 0)
    min_substring = ""

    while right < len(s):
        # 如果当前窗口内不重复字符个数小于k,继续扩大窗口
        if distinct_count < k:
            char_counts[s[right]] += 1
            if char_counts[s[right]] == 1:
                distinct_count += 1
            right += 1
        # 如果当前窗口内不重复字符个数等于k,尝试缩小窗口
        elif distinct_count == k:
            if min_substring == "" or len(s[left:right]) < len(min_substring):
                min_substring = s[left:right]
            if char_counts[s[left]] == 1:
                distinct_count -= 1
            char_counts[s[left]] -= 1
            left += 1
        # 如果当前窗口内不重复字符个数大于k,缩小窗口
        else:
            if char_counts[s[left]] == 1:
                distinct_count -= 1
            char_counts[s[left]] -= 1
            left += 1

    # 最后需要判断一下,如果在整个过程中没有找到符合条件的子串,返回空字符串
    return min_substring

代码中用到了Python内置的defaultdict结构,用来统计每个字符出现的次数。我们使用一个左右指针来维护滑动窗口,然后在滑动窗口过程中更新不重复的字符个数和每个字符出现的次数。如果当前不重复的字符个数等于K,则尝试缩小窗口以找到最优解。如果当前不重复的字符个数小于K,则左指针不动,右指针继续向右移动。如果当前不重复的字符个数大于K,则左指针向右移动。在整个过程中,我们不断更新最小长度的子串,并最终返回其结果。

这段代码的时间复杂度是O(n),其中n是字符串s的长度,空间复杂度是O(n),其中n是字符串s的长度。