[LeetCode 992] Subarrays with K Different Integers

Given an array A of positive integers, call a (contiguous, not necessarily distinct) subarray of A good if the number of different integers in that subarray is exactly K.

(For example, [1,2,3,1,2] has 3 different integers: 12, and 3.)

Return the number of good subarrays of A.

 

Example 1:

Input: A = [1,2,1,2,3], K = 2
Output: 7
Explanation: Subarrays formed with exactly 2 different integers: [1,2], [2,1], [1,2], [2,3], [1,2,1], [2,1,2], [1,2,1,2].

Example 2:

Input: A = [1,2,1,3,4], K = 3
Output: 3
Explanation: Subarrays formed with exactly 3 different integers: [1,2,1,3], [2,1,3], [1,3,4].

 

Note:

  1. 1 <= A.length <= 20000
  2. 1 <= A[i] <= A.length
  3. 1 <= K <= A.length

Key Observation:

1. The total number of such subarrays is the sum of the number of subarrays of K different integers that end at A[0], A[1], ..... A[n - 1].

2. Given an ending index i, the number of subarrays with K different integers that end at A[i] is the difference between the number of subarrays with <= K different integers and the number of subarrays with < K different integers.  If we keep two running windows for these two cases <= K and < K,  the count different is equivalent with the difference between the two left pointers of these two windows. (The right pointers are the same as both windows end at A[i]).

class Solution {
    private class Window {
        Map<Integer, Integer> count;
        int distinctCnt;

        Window() {
            count = new HashMap();
            distinctCnt = 0;
        }

        void add(int x) {
            count.put(x, count.getOrDefault(x, 0) + 1);
            if (count.get(x) == 1) {
                distinctCnt++;
            }
        }

        void remove(int x) {
            count.put(x, count.get(x) - 1);
            if (count.get(x) == 0) {
                distinctCnt--;
            }
        }

        int different() {
            return distinctCnt;
        }
    }
    public int subarraysWithKDistinct(int[] A, int K) {
        Window window1 = new Window();
        Window window2 = new Window();
        int ans = 0, left1 = 0, left2 = 0;

        for (int right = 0; right < A.length; ++right) {
            int x = A[right];
            window1.add(x);
            window2.add(x);

            while (window1.different() > K) {
                window1.remove(A[left1]);
                left1++;
            }
                
            while (window2.different() >= K) {
                window2.remove(A[left2]);      
                left2++;
            }

            ans += left2 - left1;
        }

        return ans;
    }
}
原文地址:https://www.cnblogs.com/lz87/p/12258549.html