leetcode 992. K 个不同整数的子数组

题意:

给定一个正整数数组 A,如果 A 的某个子数组中不同整数的个数恰好为 K,则称 A 的这个连续、不一定独立的子数组为好子数组

(例如,[1,2,3,1,2] 中有 3 个不同的整数:12,以及 3。)

返回 A 中好子数组的数目。

 

示例 1:

输出:A = [1,2,1,2,3], K = 2
输入:7
解释:恰好由 2 个不同整数组成的子数组:[1,2], [2,1], [1,2], [2,3], [1,2,1], [2,1,2], [1,2,1,2].

示例 2:

输入:A = [1,2,1,3,4], K = 3
输出:3
解释:恰好由 3 个不同整数组成的子数组:[1,2,1,3], [2,1,3], [1,3,4].

提示:

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

 

思路:

采用滑动窗口,对于每个A[right],考虑两种情况:

1.一种是 A[right] 是已经出现过的数字,那么只要以A[right-1]为结尾的“好子数组”都肯定满足“好子数组”的条件,这个时候只需要记录以A[right-1]为结尾的“好子数组”的数目,然后加上left向右收缩得到的增量;

2.一种是 A[right] 是新的数字,那么需要将left往右收缩,满足当前滑动窗口内不同数字为K,然后left再尽可能往右缩,得到的增量就是当前情况的“好子数组”个数。

让我们通过一个例子来形象化上面的思路,考虑数组:1 1 2 1 1 2 2 3

我们维护一个pre值,初始化为1

a[2]=2,left向右缩到位置1,pre=2,ans+=pre,此时满足题意的有 1 1 2、1 2

a[3]=1,left向右缩到位置2,pre=3,ans+=pre,此时满足题意的有 1 1 2 1、1 2 1、2 1

a[4]=1,left不用缩,pre=3,ans+=pre,此时满足题意的有 1 1 2 1 1、1 2 1 1、2 1 1

a[5]=2,left向右缩到位置4,pre=5,ans+=pre,此时满足题意的有 1 1 2 1 1 2、1 2 1 1 2、2 1 1 2、1 1 2、1 2

a[6]=2,left不用缩,pre=5,ans+=pre,此时满足题意的有 1 1 2 1 1 2 2、1 2 1 1 2 2、2 1 1 2 2、1 1 2 2、1 2 2

a[7]=3,此时滑动窗口中不同数字大于K,先讲left缩到位置5满足要求,将pre置为1,然后再往右缩到位置6,pre=2,ans+=pre,此时满足题意得有 2 2 3、2 3

综上所述,当left不能缩的时候,就相当于是在之前统计的情况上后面加上当前数字;可以缩,就相当于多了left在向右缩的过程中出现的情况

 1 class Solution {
 2 public:
 3     int num[20010];
 4     int subarraysWithKDistinct(vector<int>& A, int K) {
 5         int cnt=0,ans=0,pre=1,l=0,r=0;
 6         while(r<A.size()){
 7             num[A[r]]++;
 8             if(num[A[r++]]==1)cnt++;
 9             if(cnt<K)continue;
10             if(cnt==K){
11                 while(num[A[l]]-1>=1)pre++,num[A[l]]--,l++;
12                 ans+=pre;
13             }
14             else {
15                 while(num[A[l]]-1>=1)num[A[l]]--,l++;
16                 num[A[l]]--; l++;
17                 pre=1; cnt--;
18                 while(num[A[l]]-1>=1)pre++,num[A[l]]--,l++;
19                 ans+=pre;
20             }
21         }
22         return ans;
23     }
24 };
View Code
posted @ 2019-11-07 21:58  ljy3268  阅读(439)  评论(0编辑  收藏  举报