zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    常见的7种排序算法
    ZooKeeper
    线上问题排查(2)——JDK内置工具
    Java并发编程:深入剖析ThreadLocal
    没有main的hello world 程序——Java 分类: java 2015-06-24 16:20 11人阅读 评论(0) 收藏
    Django笔记 —— 模型
    Django笔记 —— MySQL安装
    USACO Section2.3 Controlling Companies 解题报告 【icedream61】
    USACO Section2.3 Money Systems 解题报告 【icedream61】
    USACO Section2.3 Zero Sum 解题报告 【icedream61】
  • 原文地址:https://www.cnblogs.com/ljy08163268/p/11815955.html
Copyright © 2011-2022 走看看