Longest Substring with At Most K Distinct Characters

medium sliding window hash map

Problem

Given a string s and an integer k, return the length of the longest substring of s that contains at most k distinct characters.

Inputs = "eceba", k = 2
Output3
"ece" — 2 distinct, length 3.

def length_of_longest(s, k):
    cnt = {}
    l = best = 0
    for r, ch in enumerate(s):
        cnt[ch] = cnt.get(ch, 0) + 1
        while len(cnt) > k:
            cnt[s[l]] -= 1
            if cnt[s[l]] == 0: del cnt[s[l]]
            l += 1
        best = max(best, r - l + 1)
    return best
function lengthOfLongestSubstringKDistinct(s, k) {
  const cnt = new Map();
  let l = 0, best = 0;
  for (let r = 0; r < s.length; r++) {
    cnt.set(s[r], (cnt.get(s[r]) || 0) + 1);
    while (cnt.size > k) {
      cnt.set(s[l], cnt.get(s[l]) - 1);
      if (cnt.get(s[l]) === 0) cnt.delete(s[l]);
      l++;
    }
    best = Math.max(best, r - l + 1);
  }
  return best;
}
class Solution {
    public int lengthOfLongestSubstringKDistinct(String s, int k) {
        Map cnt = new HashMap<>();
        int l = 0, best = 0;
        for (int r = 0; r < s.length(); r++) {
            cnt.merge(s.charAt(r), 1, Integer::sum);
            while (cnt.size() > k) {
                cnt.merge(s.charAt(l), -1, Integer::sum);
                if (cnt.get(s.charAt(l)) == 0) cnt.remove(s.charAt(l));
                l++;
            }
            best = Math.max(best, r - l + 1);
        }
        return best;
    }
}
int lengthOfLongestSubstringKDistinct(string s, int k) {
    unordered_map cnt;
    int l = 0, best = 0;
    for (int r = 0; r < (int)s.size(); r++) {
        cnt[s[r]]++;
        while ((int)cnt.size() > k) {
            if (--cnt[s[l]] == 0) cnt.erase(s[l]);
            l++;
        }
        best = max(best, r - l + 1);
    }
    return best;
}
Time: O(n) Space: O(k)