返回

LeetCode——替换后的最长重复字符(滑动窗口)

前端

程序员在算法解决问题的时候,时间复杂度和空间复杂度是最关注的指标之一,特别是面对大型数据集的时候,更要多加留意。LeetCode最近出了一道算法题,叫做“替换后的最长重复字符”,要求你从一个字符串中找到一个最长的重复字符子串,并允许最多替换一个字符,才满足为最长重复字符子串。

这道题乍一看可能有些难以下手,但其实我们可以运用滑动窗口的方法来解决,在介绍滑动窗口之前,我们先来看看什么是最长重复字符子串。

简单来说,最长重复字符子串是指在一个字符串中,连续出现最多的重复字符的子串,例如,在字符串"abcabcabc"中,最长重复字符子串就是"abcabc",因为它是连续出现最多的重复字符的子串。

而滑动窗口是一种常用的算法技术,它可以帮助我们快速找到最长重复字符子串,其核心思想是维护一个滑动窗口,在这个窗口中,我们统计每个字符出现的次数,然后根据统计结果,移动滑动窗口,直到窗口中的字符数满足要求。

使用滑动窗口算法解决这道题的步骤如下:

  1. 构造一个数组,该数组拥有26个元素,下标代表的是大写字母A-Z,将其所有元素初始化为0,这个数组用来统计窗口中的每个字符出现的次数。
  2. 定义滑动窗口的左右边界和滑动窗口中出现次数最多的字母。
  3. 遍历字符串中的每个字符,如果该字符在滑动窗口中,那么统计其出现的次数,并更新窗口中出现次数最多的字母。
  4. 如果该字符不在滑动窗口中,那么移动滑动窗口的左边界,直到窗口中的字符数满足要求,然后统计该字符出现的次数,并更新窗口中出现次数最多的字母。
  5. 重复步骤3和步骤4,直到遍历完整个字符串。
  6. 返回窗口中出现次数最多的字母的个数。

代码如下:

def findLongestRepeatingCharacter(s, k):
    """
    :type s: str
    :type k: int
    :rtype: int
    """
    freq = [0] * 26
    left, right = 0, 0
    maxLen = 0
    maxCount = 0

    while right < len(s):
        freq[ord(s[right]) - ord('A')] += 1
        maxCount = max(maxCount, freq[ord(s[right]) - ord('A')])
        while right - left + 1 - maxCount > k:
            freq[ord(s[left]) - ord('A')] -= 1
            left += 1
        maxLen = max(maxLen, right - left + 1)
        right += 1

    return maxLen


print(findLongestRepeatingCharacter("abcabcabc", 2))  # 6
print(findLongestRepeatingCharacter("aabbbbbb", 2))  # 5
print(findLongestRepeatingCharacter("cddceec", 2))  # 3