public static int findLength(String str, int k) {
// Note: We're keeping track of GLOBAL max, NOT LOCAL max
Map<Character, Integer> hm = new HashMap<>();
int s = 0, globalMaxFreq = 0, maxLength = 0;
for(int e = 0; e < str.length(); e++)
{
// Note: hm correctly keeps track of the char frequencies from s -> e
hm.put(str.charAt(e), hm.getOrDefault(str.charAt(e), 0) + 1);
// Notice if globalMaxFreq increases, it means the repeating characters are denser
// in this window than the last, and therefore this will be the new longest window
// (Note: maxLength = globalMaxFreq + k, when str.length is long enough of couse)
globalMaxFreq = Math.max(globalMaxFreq, hm.get(str.charAt(e)));
// That fact will be reflected here, since this if condition will not be met,
// even if it is met last iteration
if (e - s + 1 > globalMaxFreq + k)
{
hm.put(str.charAt(s), hm.get(str.charAt(s) - 1));
s++;
}
// and maxLength will be updated accordingly
maxLength = e - s + 1;
}
return maxLength;
}