Subarrays with K Different Integers

hard array hash map sliding window counting

Problem

Return the number of subarrays of nums that contain exactly k distinct integers.

Inputnums = [1,2,1,2,3], k = 2
Output7
Exactly K = atMost(K) − atMost(K - 1).

def subarraysWithKDistinct(nums, k):
    def atMost(K):
        cnt = {}
        l = total = 0
        for r, x in enumerate(nums):
            cnt[x] = cnt.get(x, 0) + 1
            while len(cnt) > K:
                cnt[nums[l]] -= 1
                if cnt[nums[l]] == 0: del cnt[nums[l]]
                l += 1
            total += r - l + 1
        return total
    return atMost(k) - atMost(k - 1)
function subarraysWithKDistinct(nums, k) {
  function atMost(K) {
    const cnt = new Map();
    let l = 0, total = 0;
    for (let r = 0; r < nums.length; r++) {
      cnt.set(nums[r], (cnt.get(nums[r]) || 0) + 1);
      while (cnt.size > K) {
        cnt.set(nums[l], cnt.get(nums[l]) - 1);
        if (cnt.get(nums[l]) === 0) cnt.delete(nums[l]);
        l++;
      }
      total += r - l + 1;
    }
    return total;
  }
  return atMost(k) - atMost(k - 1);
}
class Solution {
    public int subarraysWithKDistinct(int[] nums, int k) {
        return atMost(nums, k) - atMost(nums, k - 1);
    }
    int atMost(int[] nums, int K) {
        Map<Integer, Integer> cnt = new HashMap<>();
        int l = 0, total = 0;
        for (int r = 0; r < nums.length; r++) {
            cnt.merge(nums[r], 1, Integer::sum);
            while (cnt.size() > K) {
                cnt.merge(nums[l], -1, Integer::sum);
                if (cnt.get(nums[l]) == 0) cnt.remove(nums[l]);
                l++;
            }
            total += r - l + 1;
        }
        return total;
    }
}
int atMost(vector<int>& nums, int K) {
    unordered_map<int, int> cnt;
    int l = 0, total = 0;
    for (int r = 0; r < (int)nums.size(); r++) {
        cnt[nums[r]]++;
        while ((int)cnt.size() > K) {
            if (--cnt[nums[l]] == 0) cnt.erase(nums[l]);
            l++;
        }
        total += r - l + 1;
    }
    return total;
}
int subarraysWithKDistinct(vector<int>& nums, int k) { return atMost(nums, k) - atMost(nums, k - 1); }
Time: O(n) Space: O(n)