Longest Repeating Character Replacement - Complete Solution Guide
Longest Repeating Character Replacement is LeetCode problem 424, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
You are given a string s and an integer k . You can choose any character of the string and change it to any other uppercase English character. You can perform this operation at most k times. Return the length of the longest substring containing the same letter you can get after performing the above operations . Example 1: Input: s = "ABAB", k = 2 Output: 4 Explanation: Replace the two 'A's with two 'B's or vice versa. Example 2: Input: s = "AABABBA", k = 1 Output: 4 Explanation: Replace the one
Detailed Explanation
The problem asks us to find the length of the longest substring in a given string `s` that contains the same letter after performing at most `k` character replacements. We can change any character in the string to any other uppercase English character. The goal is to maximize the length of a substring consisting of the same character after these replacements. For example, if `s = "ABAB"` and `k = 2`, we can replace the two 'A's with 'B's (or vice versa) to get a substring of length 4 ('BBBB' or 'AAAA').
Solution Approach
The solution uses a sliding window approach with two pointers, `left` and `right`. We expand the window by incrementing the `right` pointer and update a frequency map to keep track of the character counts within the window. We also maintain `max_freq`, which stores the maximum frequency of any character seen so far within the window. If the difference between the window size (`right - left + 1`) and `max_freq` is greater than `k`, it means we need to shrink the window by incrementing the `left` pointer. We also decrement the count of the character that `left` is pointing to. We continuously update `max_len` to keep track of the longest valid window encountered so far. The key idea is to maintain a window that, after at most `k` replacements, can be a substring of the same character.
Step-by-Step Algorithm
- Step 1: Initialize `left = 0`, `max_freq = 0`, `max_len = 0`, and `counts = [0] * 26` (an array to store the frequencies of each character).
- Step 2: Iterate through the string `s` using the `right` pointer (from 0 to `len(s) - 1`).
- Step 3: Update the frequency count of the character at the `right` pointer: `counts[ord(s[right]) - ord('A')] += 1`.
- Step 4: Update `max_freq` to be the maximum frequency encountered so far: `max_freq = max(max_freq, counts[ord(s[right]) - ord('A')])`.
- Step 5: Check if the current window is valid: `if (right - left + 1) - max_freq > k`. If it's not valid, it means we need to shrink the window.
- Step 6: If the window is not valid, decrement the frequency count of the character at the `left` pointer: `counts[ord(s[left]) - ord('A')] -= 1`. Increment the `left` pointer: `left += 1`.
- Step 7: Update `max_len` to be the maximum window length encountered so far: `max_len = max(max_len, right - left + 1)`.
- Step 8: After the loop finishes, return `max_len`.
Key Insights
- Insight 1: The problem can be solved using a sliding window approach. We need to maintain a window and keep track of the most frequent character within that window.
- Insight 2: If the number of characters within the window minus the count of the most frequent character is less than or equal to `k`, then the window is a valid candidate substring.
- Insight 3: We don't necessarily need to shrink the window; we can just slide the right edge and maintain `max_len`. The reason is that if `(right - left + 1) - max_freq > k`, we shift the left bound; if not, we keep the left bound and update `max_len`. So if the window is invalid, we won't update `max_len`. This works because we are only concerned with the *longest* valid substring. Even if we have an invalid window now, we keep its length and shift its left pointer if it's invalid. We maintain the `max_freq` value, which may not be the accurate maximum frequency of the current window; this works because only the length of the window matters.
- Insight 4: Use an array of length 26 as a hashmap to store character frequencies instead of a dictionary. Since we only use uppercase letters, this is much more efficient.
Complexity Analysis
Time Complexity: O(n)
Space Complexity: O(1)
Topics
This problem involves: Hash Table, String, Sliding Window.
Companies
Asked at: ByteDance, Flipkart, MathWorks, PayU, PhonePe, Pocket Gems, Turing, UiPath, Yandex, Zepto.