We need to find the longest substring where, after changing at most k characters, every character in the substring is the same. For any given substring, how many changes are needed to make all characters identical?
If a substring has length L and the most frequent character in it appears maxFreq times, we keep those maxFreq characters and change the remaining L - maxFreq to match them. So a substring is valid when L - maxFreq <= k.
Every approach builds on this condition. We are looking for the longest substring where the number of non-majority characters is at most k.
s.length up to 10^5 means O(n^2) is borderline. An O(n) or O(n log n) approach is preferred.k can be as large as s.length, meaning we might be able to change every character. In that case, the answer is the entire string length.Try every possible substring and check whether it can be turned into a repeating-character string with at most k replacements. For each starting index, expand the substring one character at a time, maintaining a frequency count. At each step, the number of replacements needed is windowLength - maxFrequency. Track the longest valid substring. For a fixed start, every step adds 1 to the window length and at most 1 to maxFreq, so windowLength - maxFreq never decreases as the window grows. Once it exceeds k, it stays above k, so we stop and move the start forward.
left from 0 to n - 1maxFreq variableright from left to n - 1, updating the frequency of s[right]maxFreq to be the maximum value in the frequency array(right - left + 1) - maxFreq <= k, update the answer with the current window length(right - left + 1) - maxFreq > k, break (no point expanding further from this left)break helps in practice but doesn't change worst-case behavior.For each starting position, this rebuilds the frequency count from scratch. The next approach keeps a single frequency count and reuses it as the window moves, instead of resetting it for every start.
Instead of trying every starting point independently, we use two pointers to maintain a single window that we expand and shrink. The idea: expand right one step at a time. After each expansion, check if the window is still valid (windowSize - maxFreq <= k). If not, shrink from the left until it becomes valid again.
The frequency array updates incrementally. When right moves forward, we increment one count. When left moves forward, we decrement one count. No redundant work.
When we shrink the window by moving left forward, the maxFreq might decrease. We recompute it by scanning all 26 entries in the frequency array. Since 26 is a constant, this does not affect the overall O(n) time complexity.
left = 0, maxLen = 0right from 0 to n - 1freq[s[right]]maxFreq as the maximum value in the frequency array(right - left + 1) - maxFreq > k, decrement freq[s[left]], increment left, and recompute maxFreqmaxLen = max(maxLen, right - left + 1)maxLenEvery time we shrink the window, we recompute maxFreq by scanning all 26 characters. The answer can only improve when maxFreq increases, so the next approach keeps maxFreq at its highest value seen so far and never recomputes it downward.
We never need to decrease maxFreq. The answer is the largest window length ever recorded, and a window can only beat the current best if its length exceeds the best. Since a valid window of length L requires L - maxFreq <= k, a longer valid window needs a higher maxFreq. A smaller maxFreq can never produce a larger answer, so we can ignore it.
Instead of shrinking the window with a while loop until it is valid, we use a single if. When the window is invalid, we move left forward by exactly one position and continue. The window length then either stays the same or grows, never dropping below the largest valid length seen so far.
maxFreq can become stale: after left advances, the true most-frequent count in the window may be lower than maxFreq. That is safe. A stale maxFreq only makes the validity test windowLen - maxFreq <= k easier to pass, so the window never shrinks. But the recorded maxLen only grows when windowLen itself grows, and windowLen grows only after right advances. The window length can never exceed the largest length that was genuinely valid at the moment maxFreq last increased, so the final answer is a length that some real window actually achieved.
left = 0, maxFreq = 0, maxLen = 0right from 0 to n - 1freq[s[right]] and update maxFreq if this character's count is the new max(right - left + 1) - maxFreq > k, decrement freq[s[left]] and increment left (slide window by 1)maxLen = max(maxLen, right - left + 1)maxLenleft and right move forward at most n times each. Each step does O(1) work (no scanning of the frequency array). Strictly linear.