https://leetcode.com/problems/longest-repeating-character-replacement/
滑动窗口的典型,还是有一些trick的
个人解答
class Solution:def characterReplacement(self, s: str, k: int) -> int:c = collections.Counter()maxCnt = 0res = 0l, r = 0, 0while r < len(s):c[s[r]] += 1maxCnt = max(maxCnt, c[s[r]])while r - l + 1 > k + maxCnt:c[s[l]] -= 1l += 1res = max(res, r - l + 1)r += 1return res
题目分析
比较容易能够想到一个基础的解法:
题目限定了字符是大写字母,也就26个嘛,对每一个都找可替换的最长子串,这个可以用sliding window解决,整体的思路还是比较直观的,直接看代码:
class Solution:def characterReplacement(self, s: str, k: int) -> int:def f(x):l, r, cnt = 0, 0, 0res = 0while r < len(s):if s[r] == x:cnt += 1while r - l + 1 > k + cnt:if s[l] == x:cnt -= 1l += 1res = max(res, r - l + 1)r += 1return resres = 0for x in string.ascii_uppercase:res = max(res, f(x))return res
但是,本题目其实有更优雅更高效的处理方式,对每个字母做sliding window做了很多无用功,可以同时进行。
对于一个(l, r)的区间,我们并不关注到底是哪个字母出现最多,只关注出现最多的数量,因此,只要维护当前区间,每个字母的数量,并时刻取最大的数量就可以了。
有且只有保证区间的长度,没有超过区间内最大字母个数+可替换个数,这个区间一定是合法的,找出最长的合法区间即可。
