📜  每个字符的频率小于等于 k 的最长子串(1)

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

每个字符的频率小于等于k的最长子串

给定一个字符串和一个正整数k,找到该字符串中每个字符出现频率都小于等于k的最长子串。

例如,给定字符串"aabab"和k=2,结果为"ababa"。

算法思路
  1. 定义两个指针left和right,分别表示子串的左右两端。
  2. 定义一个字典freq,用于记录每个字符出现的次数。
  3. 当freq中某个字符的出现次数大于k时,将left右移。
  4. 每次更新字典freq,并记录当前子串的长度。
  5. 如果当前字典freq中所有字符的出现次数均小于等于k,则更新最长子串的长度,并将right右移。
代码实现
def max_substring(s: str, k: int) -> str:
    left = right = max_len = 0
    freq = {}

    while right < len(s):
        freq[s[right]] = freq.get(s[right], 0) + 1
        right += 1

        while len(freq) > k:
            freq[s[left]] -= 1
            if freq[s[left]] == 0:
                freq.pop(s[left])
            left += 1

        max_len = max(max_len, right - left)

    return s[left:left+max_len]
复杂度分析
  • 时间复杂度:$O(n)$。
  • 空间复杂度:$O(k)$,因为字典freq最多保存k个字符的出现次数。