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...