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