Longest Repeating Character Replacement
Longest Repeating Character Replacement
Given a string s of uppercase English letters and an integer k, you can replace at most k characters. Return the length of the longest substring that can be turned into all the same character using at most k replacements.
A sliding window with a running max frequency solves this in O(n).
Function signature
func CharacterReplacement(s string, k int) int
Inputs / outputs
s: uppercase English letters.k: maximum number of replacements.- Return: length of the longest valid substring.
Example
s = "AABABBA", k = 1
Output: 4
One answer: replace one 'B' to make "AABA".
Constraints
0 <= len(s) <= 100_0000 <= k <= len(s)
Core idea (near-solution)
Maintain a window [l, r] and the count of each letter inside it. Let maxFreq be the maximum frequency of any single character in the window.
The number of replacements needed is windowSize - maxFreq. If that exceeds k, shrink from the left.
Invariant: windowSize - maxFreq <= k for the current window.
Algorithm (step-by-step)
- Initialize
l = 0,best = 0,maxFreq = 0, and a 26-count array. - For each
rfrom 0 tolen(s)-1:- Increment the count for
s[r]and updatemaxFreq. - While
(r-l+1) - maxFreq > k:- Decrement the count for
s[l]and incrementl.
- Decrement the count for
- Update
best = max(best, r-l+1).
- Increment the count for
- Return
best.
Correctness sketch
- Invariant:
windowSize - maxFreq <= kfor the current window. - The window state exactly matches the elements in
s[l..r]. - Shrinking/expanding preserves validity, so any recorded window is correct.
- The best recorded window is optimal because all candidate windows are considered.
Trace (hand walkthrough)
Trace Walkthrough
Example input:
s = "AABABBA", k = 1
Output: 4
One answer: replace one 'B' to make "AABA".
Walk:
- window "AABA" (r=0..3): maxFreq=3, size-maxFreq=1 <= k, best=4
- add B -> "AABAB" size=5, maxFreq=3, 5-3=2>k -> move l to 1 ("ABAB")
- add B -> window "ABABB" size=5, maxFreq=3, 5-3=2>k -> move l to 2 ("BABB")
- best remains 4
Pitfalls to avoid
- Recomputing
maxFreqon every shrink (not needed; it can be stale and still correct). - Using this approach for non-fixed alphabets without adapting the count structure.
Complexity
- Time:
O(n) - Extra space:
O(1)(26 counts).
Implementation notes (Go)
- Track
maxFreqof any char in the window. - Window is valid while
len - maxFreq <= k; do not recompute max on shrink.
Run tests to see results
No issues detected