−=
count letter counts inside the window · green = count equals maxf · dashed tiles in the window = the ones to replace · dashed outline = best so far
public int characterReplacement(String s, int k) { int[] count = new int[26]; int res = 0; int l = 0; int maxf = 0; // highest count seen in a window for (int r = 0; r < s.length(); r++) { count[s.charAt(r) - 'A']++; maxf = Math.max(maxf, count[s.charAt(r) - 'A']); while ((r - l + 1) - maxf > k) { count[s.charAt(l) - 'A']--; l++; } res = Math.max(res, r - l + 1); } return res;}
- l
- —
- r
- —
- maxf
- 0
- count
- {}
- res
- 0
Why it works
- Brute force checks every substring: a substring works if its length minus its most common letter's count is at most
k. O(n²) substrings, each checked with 26 counts. - Keep the most common letter, replace the rest. A window is valid when
(r − l + 1) − maxf ≤ k. Growrevery step; when the window needs more thankreplacements, drop letters from the left until it fits again. - Why O(n):
landronly move right, so the inner loop does O(n) work in total. Thecountarray has 26 slots. - Pitfall, or rather a trick:
maxfnever goes down when the window shrinks, so it can be stale. That is safe:resonly grows when a window beats the old best, which needs a real count above the oldmaxf. - Related: Longest Substring Without Repeating Characters uses the same grow-right, shrink-left loop with a different validity test.