## Longest Repeating Character Replacement

###### DESCRIPTION (credit Leetcode.com)

Write a function to find the length of the longest substring containing the same letter in a given string s, after performing at most k operations in which you can choose any character of the string and change it to any other uppercase English letter.

###### EXAMPLES

Input:

`s = "BBABCCDD" k = 2`

Output:

`5`

Explanation: Replace the first 'A' and 'C' with 'B' to form "BBBBBCCDD". The longest substring with identical letters is "BBBBB", which has a length of 5.

Run your code to see results here

## Explanation

In order for a substring to be valid, k + the frequency of the most frequent character in the substring must be greater than or equal to the length of the substring.

For example, if k = 2, and the substring is AABBB, then the most frequent character is B, which shows up 3 times. The substring is valid because 2 + 3 >= 5.

However, if k = 2 and the substring is AAABBB, then the substring is invalid because 2 + 3 < 6.

We use this fact to solve this problem with a variable-length sliding window to iterate over all valid substrings, and return the longest of those lengths at the end. To represent the state of the current window, we keep track of two variables:

- state: A dictionary mapping each character to the number of times it appears in the current window.
- max_freq: The maximum number of times a single character has appeared in
**any**window so far.

We start by extending the current window until it becomes invalid (i.e. k + max_freq < window length).

def characterReplacement(s, k):state = {}max_freq = 0max_length = 0start = 0for end in range(len(s)):state[s[end]] = state.get(s[end], 0) + 1max_freq = max(max_freq, state[s[end]])if k + max_freq < end - start + 1:state[s[start]] -= 1start += 1max_length = max(max_length, end - start + 1)return max_length

At this point, the longest substring we have found so far is BCBAB, which has a length of 5 (max_freq = 3 + k = 2).

Now, whenever we try to extend the current window to length 6, it will be invalid unless the character we just included in the window shows up 4 times. So each time we increase the window to length 6, we immediately shrink the window to length 5 until we find a character which shows up 4 times.

def characterReplacement(s, k):state = {}max_freq = 0max_length = 0start = 0for end in range(len(s)):state[s[end]] = state.get(s[end], 0) + 1max_freq = max(max_freq, state[s[end]])if k + max_freq < end - start + 1:state[s[start]] -= 1start += 1max_length = max(max_length, end - start + 1)return max_length

This continues until we reach the end of the string, at which point we return the length of the longest substring we have found so far.

def characterReplacement(s, k):state = {}max_freq = 0max_length = 0start = 0for end in range(len(s)):state[s[end]] = state.get(s[end], 0) + 1max_freq = max(max_freq, state[s[end]])if k + max_freq < end - start + 1:state[s[start]] -= 1start += 1max_length = max(max_length, end - start + 1)return max_length

## Solution

def characterReplacement(s, k):state = {}max_freq = 0max_length = 0start = 0for end in range(len(s)):state[s[end]] = state.get(s[end], 0) + 1max_freq = max(max_freq, state[s[end]])if k + max_freq < end - start + 1:state[s[start]] -= 1start += 1max_length = max(max_length, end - start + 1)return max_length

Loading comments...