150NeetCode 150

17.Longest Repeating Character Replacement

MediumBlind 75Sliding Window ยท 3/6

Problem

You are given a string s of uppercase English letters and an integer k. You may pick any character of the string and change it to any other uppercase letter, performing at most k such changes.

Return the length of the longest substring that can be made to contain one repeated letter after the changes.

Examples

Input:  s = "ABAB", k = 2
Output: 4
Explanation: Replace both 'A's with 'B' (or both 'B's with 'A') โ†’ "BBBB".
Input:  s = "AABABBA", k = 1
Output: 4
Explanation: Replace the 'A' at index 3 โ†’ "AABBBBA"; the substring "BBBB" has length 4.

Constraints

  • 1 <= s.length <= 10^5
  • s consists of only uppercase English letters.
  • 0 <= k <= s.length

๐Ÿ’ก Key Insight

A window can be turned into one letter iff the number of characters that are not its most frequent letter fits in the budget: windowLength - maxFreq <= k. Slide a window, growing on the right and shrinking on the left whenever that condition breaks. Because we only care about windows that beat the current best, maxFreq never needs to be decreased โ€” this makes each step O(1).

Brute Force

TimeO(nยฒ)SpaceO(1)

Intuition

Fix a start index i, extend the end j one character at a time while maintaining letter counts and the highest count. The substring s[i..j] is valid when (j - i + 1) - maxCount <= k.

Algorithm

  1. best = 0.
  2. For each start i: reset count[26] and maxCount = 0.
  3. For each end j >= i: increment count[s[j]], update maxCount; if (j - i + 1) - maxCount <= k, update best.
  4. Return best.

Visualization

s = "AABABBA", k = 1

i=0: A A B A B ...  "AABA" needs 1 change โœ“ len 4; "AABAB" needs 2 โœ—
i=1: A B A B B ...  "ABAB" needs 2 โœ— ...
i=2: B A B B A      "BABB" needs 1 โœ“ len 4
best = 4

Code

java
class Solution {
    public int characterReplacement(String s, int k) {
        int n = s.length();
        int best = 0;
        for (int i = 0; i < n; i++) {
            int[] count = new int[26];
            int maxCount = 0;
            for (int j = i; j < n; j++) {
                int idx = s.charAt(j) - 'A';
                count[idx]++;
                maxCount = Math.max(maxCount, count[idx]);
                // characters that must be replaced = length - most frequent letter
                if ((j - i + 1) - maxCount <= k) {
                    best = Math.max(best, j - i + 1);
                }
            }
        }
        return best;
    }
}

Complexity

  • Time: O(nยฒ) โ€” all n(n+1)/2 substrings are examined.
  • Space: O(1) โ€” a 26-slot count array.

Complexity Comparison

Approach Time Space
Brute Force O(nยฒ) O(1)
Sliding Window (recompute max) O(26 ยท n) O(1)
Sliding Window (stale maxFreq) O(n) O(1)

Common Pitfalls

  • Trying to pick "the" target letter in advance โ€” the best letter differs per window; the length - maxFreq formula handles all letters at once.
  • Worrying that a stale maxFreq gives wrong answers: it can only keep an invalid window at the same size as a previously valid one, so the returned maximum is still correct.
  • Using right - left instead of right - left + 1 for the window length.
  • Forgetting k can be 0; the formula still works (window must be a single repeated letter).