Longest Repeating Character Replacement

Longest Repeating Character Replacement

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 'A' in the middle with 'B' and form "AABBBBA".
The substring "BBBB" has the longest repeating letters, which is 4.

Constraints:

  • 1 <= s.length <= 10<sup>5</sup>

  • s consists of only uppercase English letters.

0 <= k <= s.length

Approach

  • Initialize a hashmap, and two variables to track the length of the longest valid substring and the left endpoint of the window.

  • Loop through the string using a sliding window with the right endpoint r, and for each r:

    a. Add the current character to the hashmap and update its frequency count.

    b. If the number of characters that need to be replaced to make all characters the same is greater than k, move the left endpoint of the window and shrink the window from the left until the number of characters that need to be replaced is less than or equal to k.

    c. Update the length of the longest valid substring seen so far.

  • Return the length of the longest valid substring.

Time Complexity: O(N) for sliding window approach

Space Complexity: O(k), where k is the number of distinct characters in the input string s.

Code

public class Solution {
    public int characterReplacement(String s, int k) {
        // Create a hashmap to store the frequency count of each character
        HashMap<Character, Integer> hm = new HashMap<>();

        // Initialize variables to keep track of the longest substring and    the left pointer
        int ans = 0;
        int l = 0;

        // Loop through the string with a sliding window
        for (int r = 0; r < s.length(); r++) {
            // Add the current character to the hashmap and update its frequency count
            hm.put(s.charAt(r), 1 + hm.getOrDefault(s.charAt(r), 0));

            // If the number of characters that need to be changed is greater than k, move the left pointer
            while ((r - l + 1) - Collections.max(hm.values()) > k) {
                hm.put(s.charAt(l), hm.get(s.charAt(l)) - 1);
                l += 1;
            }

            // Update the length of the longest valid substring seen so far
            ans = Math.max(ans, r - l + 1);
        }

        // Return the length of the longest valid substring
        return ans;
    }
}

More solutions can be found at:

Github