pythonsliding-window

Leetcode 424. Longest Repeating Character Replacement: Right Pointer Incrementation


I'm trying to solve Leetcode 424. Longest Repeating Character Replacement. Why is this code not working, I cannot get my head around it.

class Solution:
    def characterReplacement(self, s: str, k: int) -> int:
        l, r = 0, 0
        res = 0
        char_count = {}

        while r < len(s):
            char_count[s[r]] = char_count.get(s[r], 0) + 1
            substr_len = r - l + 1
            
            if substr_len - max(char_count.values()) <= k:
                res = max(res, substr_len)
                r += 1
            else:
                char_count[s[l]] -= 1
                l += 1
            
        
        return res

Test case:

Input
s =
"AABABBA"

k =
1

Output
5

Expected
4

While this works:

class Solution:
    def characterReplacement(self, s: str, k: int) -> int:
        l, r = 0, 0
        res = 0
        char_count = {}

        while r < len(s):
            char_count[s[r]] = char_count.get(s[r], 0) + 1
            substr_len = r - l + 1
            r += 1
            
            if substr_len - max(char_count.values()) <= k:
                res = max(res, substr_len)
            else:
                char_count[s[l]] -= 1
                l += 1
            
        
        return res

The difference between the two codes is where the right pointer is incremented. Shouldn't the right pointer only be incremented if the substr_len - max(char_count.values()) <= k? Isn't this what the first code is doing?, while the second code always increments the right pointer, even if substr_len > k?


Solution

  • The problem is that in case substr_len - max(char_count.values()) <= k is false, you are only decreasing the left bounds character count while staying at the same right bounds position. Therefore, on the next iteration you will count the right bounds character again. You would need to decrease char_count[s[r]] -= 1 as well in the else-block.

    That your second code works is because you are searching for the maximum possible substring length. Before entering the else-block the first time the first and the second code behave identical. When you enter the else-block you are shifting the left and the right border (instead of only the left one). But that is not a problem, because you are not interested in substrings which are shorter in length. You never have to decrease your interval length in your algorithm.

    I hope, that this was understandable. Comment if you need more explanation :)