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].

思路:跟 Substrings with exactly K distinct chars ,把问题转换为 at most k的count,这样就好做,然后用公式f(k) - f(k-1); 为什么这么做转换,是因为 同向双指针是 j 一直往前面走,j不能回头的,但是这个题目要求是要求所有的 diff integer  = k 的subarray;

[1,2,1,2]  k = 2这个为例: [1,2], [1,2,1], [1,2,1,2], [2,1,2], [1,2] 都是答案,但是j没办法回去;所以计算是有问题的;所以不能单单扫一遍,是计算不出来的; res += j - i ;  代表的是以  j -1 为结尾的,满足at most k chars的个数;

class Solution {
    public int subarraysWithKDistinct(int[] A, int K) {
        if(A == null || A.length == 0) {
            return 0;
        }
        return getAtMostK(A, K) - getAtMostK(A, K - 1);
    }
    
    private int getAtMostK(int[] A, int k) {
        int res = 0;
        int j = 0;
        int count = 0;
        int[] counts = new int[A.length + 1];
        for(int i = 0; i < A.length; i++) {
            // move j;
            while(j < A.length && count <= k) {
                if(counts[A[j]] == 0) {
                    if(count == k) {
                        break;
                    }
                    count++;
                }
                counts[A[j]]++;
                j++;
            }
            
            // update result;
            res += j - i;
            
            // move i;
            counts[A[i]]--;
            if(counts[A[i]] == 0) {
                count--;
            }
        }
        return res;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值