Leetcode 992 具有K个不同整数的子数组 (滑动窗口)

Posted Will

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode 992 具有K个不同整数的子数组 (滑动窗口)相关的知识,希望对你有一定的参考价值。

Leetcode 992

问题描述

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: 1, 2, 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].

方法一

** Solution Java **
** 54ms, 22.96% **
** 43MB, 15.79% **
class Solution {
    public int subarraysWithKDistinct(int[] A, int K) {
        return atMostK(A, K) - atMostK(A, K - 1);
    }
    private int atMostK(int[] A, int K) {
        int i = 0, res = 0;
        Map<Integer, Integer> map = new HashMap<>();
        for (int j = 0; j < A.length; ++j) {
            if (map.getOrDefault(A[j], 0) == 0)
                --K;
            map.put(A[j], map.getOrDefault(A[j], 0) + 1);
            while (K < 0) {
                map.put(A[i], map.get(A[i]) - 1);
                if (map.get(A[i]) == 0)
                    ++K;
                ++i;
            }
            res += j - i + 1;
        }
        return res;
    }
}
** Solution Python3 **
** 636ms, 39.53% **
** 16.1MB, 100.00% **
class Solution:
    def subarraysWithKDistinct(self, A, K):
        return self.atMostK(A, K) - self.atMostK(A, K - 1)

    def atMostK(self, A, K):
        count = collections.Counter()
        res = i = 0
        for j in range(len(A)):
            if count[A[j]] == 0: K -= 1
            count[A[j]] += 1
            while K < 0:
                count[A[i]] -= 1
                if count[A[i]] == 0: K += 1
                i += 1
            res += j - i + 1
        return res

方法二

** Solution Java **
** 4ms, 97.35% **
** 42.7MB, 21.05% **
class Solution {
    public int subarraysWithKDistinct(int[] A, int K) {
        int res = 0, pre = 0;
        int[] map = new int[A.length + 1];
        for (int i = 0, j = 0, cnt = 0; i < A.length; ++i) {
            if (map[A[i]]++ == 0)
                ++cnt;
            if (cnt > K) {
                --map[A[j++]];
                --cnt;
                pre = 0;
            }
            while (map[A[j]] > 1) {
                ++pre;
                --map[A[j++]];
            }
            if (cnt == K)
                res += pre + 1;
        }
        return res;
    }
}

以上是关于Leetcode 992 具有K个不同整数的子数组 (滑动窗口)的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode 560.和为k的子数组

LeetCode 560.和为K的子数组

[LeetCode]560. 和为K的子数组(前缀和)

《LeetCode之每日一题》:52.和为K的子数组

LeetCode 2090. 半径为 k 的子数组平均值

LeetCode-560. 和为 K 的子数组