Problem
You are given a string s
and an integer k
. You can choose any character of the string and change it to any other uppercase English character. You can perform this operation at most k
times.
Return the length of the longest substring containing the same letter you can get after performing the above operations.
https://leetcode.com/problems/longest-repeating-character-replacement/
Example 1:
Input:
s = "ABAB", k = 2
Output:4
Explanation: Replace the two'A'
s with two'B'
s or vice versa.
Example 2:
Input:
s = "AABABBA", k = 1
Output:4
Explanation: Replace the one'A'
in the middle with'B'
and form"AABBBBA"
.
The substring"BBBB"
has the longest repeating letters, which is 4.
There may exists other ways to achieve this answer too.
Constraints:
1 <= s.length <= 10^5
s
consists of only uppercase English letters.0 <= k <= s.length
Test Cases
1 | class Solution: |
1 | import pytest |
Thoughts
先考虑某一个字母,比如 ‘A’。最多把 k 个其他字母改成 ‘A’,看能得到的最长的连续 ‘A’ 有多长。
设当前的子串 s[i:j]
是连续的 ‘A’,且其中有 r
个 ‘A’ 是从其他字母换过来的(0 <= i < j <= n
,0 <= r <= k
)。
如果 s[j]
是 ‘A’,或者还有替换次数尚未用完,则可以右移 j
(并更新 k
的使用次数)。
否则根据 s[i]
释放 k
的使用次数,并向右移动 i
。
设各不相同的字母总数是 C
,那么时间复杂度是 O(C * n)
,空间复杂度是 O(C)
。
PS:之前用这种滑窗法的时候,写循环的时候总是被边界条件搞得头疼。主要是在想思路的时候,往往会让区间的一头直接移动到最远,然后再移动另一头。但如果按这个方式写代码,就会引入嵌套的循环,增加更多的边界条件判定,代码看着也复杂。实际上代码里应该就一个循环,每次循环只移动一步。比如即使区间的右边界可以连续移动五步,也不要在主循环体内直接让它移动五步,而是要正常地循环五次,每次都移动一步。
Code
1 | class Solution: |
似乎不是很快,先这样吧。