Welcome to Subscribe On Youtube

3859. Count Subarrays With K Distinct Integers

Description

You are given an integer array nums and two integers k and m.

Return an integer denoting the count of subarrays of nums such that:

  • The subarray contains exactly k distinct integers.
  • Within the subarray, each distinct integer appears at least m times.

 

Example 1:

Input: nums = [1,2,1,2,2], k = 2, m = 2

Output: 2

Explanation:

The possible subarrays with k = 2 distinct integers, each appearing at least m = 2 times are:

Subarray Distinct
numbers
Frequency
[1, 2, 1, 2] {1, 2} → 2 {1: 2, 2: 2}
[1, 2, 1, 2, 2] {1, 2} → 2 {1: 2, 2: 3}

Thus, the answer is 2.

Example 2:

Input: nums = [3,1,2,4], k = 2, m = 1

Output: 3

Explanation:

The possible subarrays with k = 2 distinct integers, each appearing at least m = 1 times are:

Subarray Distinct
numbers
Frequency
[3, 1] {3, 1} → 2 {3: 1, 1: 1}
[1, 2] {1, 2} → 2 {1: 1, 2: 1}
[2, 4] {2, 4} → 2 {2: 1, 4: 1}

Thus, the answer is 3.

 

Constraints:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 105
  • 1 <= k, m <= nums.length

Solutions

Solution 1

  • class Solution {
        private int[] nums;
        private int k;
        private int m;
    
        public long countSubarrays(int[] nums, int k, int m) {
            this.nums = nums;
            this.k = k;
            this.m = m;
            return f(k) - f(k + 1);
        }
    
        private long f(int lim) {
            Map<Integer, Integer> cnt = new HashMap<>();
            long ans = 0;
            int l = 0;
            int t = 0;
    
            for (int x : nums) {
                if (cnt.merge(x, 1, Integer::sum) == m) {
                    t++;
                }
    
                while (cnt.size() >= lim && t >= k) {
                    int y = nums[l++];
                    int cur = cnt.merge(y, -1, Integer::sum);
                    if (cur == m - 1) {
                        --t;
                    }
                    if (cur == 0) {
                        cnt.remove(y);
                    }
                }
    
                ans += l;
            }
    
            return ans;
        }
    }
    
    
  • class Solution {
    public:
        long long countSubarrays(vector<int>& nums, int k, int m) {
            auto f = [&](int lim) -> long long {
                unordered_map<int, int> cnt;
                long long ans = 0;
                int l = 0;
                int t = 0;
    
                for (int x : nums) {
                    if (++cnt[x] == m) {
                        ++t;
                    }
    
                    while (cnt.size() >= lim && t >= k) {
                        int y = nums[l++];
                        if (--cnt[y] == m - 1) {
                            --t;
                        }
                        if (cnt[y] == 0) {
                            cnt.erase(y);
                        }
                    }
    
                    ans += l;
                }
    
                return ans;
            };
    
            return f(k) - f(k + 1);
        }
    };
    
    
  • class Solution:
        def countSubarrays(self, nums: list[int], k: int, m: int) -> int:
            def f(lim: int) -> int:
                cnt = Counter()
                t = 0
                ans = l = 0
                for x in nums:
                    cnt[x] += 1
                    if cnt[x] == m:
                        t += 1
                    while len(cnt) >= lim and t >= k:
                        y = nums[l]
                        cnt[y] -= 1
                        if cnt[y] == m - 1:
                            t -= 1
                        if cnt[y] == 0:
                            cnt.pop(y)
                        l += 1
                    ans += l
                return ans
    
            return f(k) - f(k + 1)
    
    
  • func countSubarrays(nums []int, k int, m int) int64 {
    	f := func(lim int) int64 {
    		cnt := make(map[int]int)
    		var ans int64
    		l := 0
    		t := 0
    
    		for _, x := range nums {
    			cnt[x]++
    			if cnt[x] == m {
    				t++
    			}
    
    			for len(cnt) >= lim && t >= k {
    				y := nums[l]
    				l++
    				cnt[y]--
    				if cnt[y] == m-1 {
    					t--
    				}
    				if cnt[y] == 0 {
    					delete(cnt, y)
    				}
    			}
    
    			ans += int64(l)
    		}
    
    		return ans
    	}
    
    	return f(k) - f(k+1)
    }
    
    
  • function countSubarrays(nums: number[], k: number, m: number): number {
        const f = (lim: number): number => {
            const cnt = new Map<number, number>();
            let ans = 0;
            let l = 0;
            let t = 0;
    
            for (const x of nums) {
                cnt.set(x, (cnt.get(x) ?? 0) + 1);
                if (cnt.get(x) === m) {
                    t++;
                }
    
                while (cnt.size >= lim && t >= k) {
                    const y = nums[l++];
                    cnt.set(y, cnt.get(y)! - 1);
    
                    if (cnt.get(y) === m - 1) {
                        t--;
                    }
    
                    if (cnt.get(y) === 0) {
                        cnt.delete(y);
                    }
                }
    
                ans += l;
            }
    
            return ans;
        };
    
        return f(k) - f(k + 1);
    }
    
    

All Problems

All Solutions