zoukankan      html  css  js  c++  java
  • Leetcode 992 Subarrays with K Different Integers

    题目链接:https://leetcode.com/problems/subarrays-with-k-different-integers/

    题意:已知一个全为正数的数组A,1<=A.length<=20000,1<=A[i]<=A.length,1<=K<=A.length,问A中恰好有K个不同的元素的子数组个数有多少个

    思路:对于考虑到数据范围较大,暴力显然不可取。对于每个位置i,如果用min_k[i] 表示起始位置为i的子数组存在k个元素的最小结束位置,用min_k_1[i] 表示起始位置为i的子数组存在k+1个不同的元素的最小结束位置,则对于起始位置为i、存在k个不同元素的的子数组的个数为min_k_1[i]-min_k[i]。

    至于如何求min_k[i]呢(和求min_k_1的方法一样)呢,可以维护一个滑动窗口,左边界为i,当滑动窗口不同元素个数小于k时,向右移动右边界,当等于k时,则左边界变为i+1,刚好用来求min_k[i+1],min_k[i+1]>=min_k[i],因此可在线性的时间内求出min_k和min_k_1,滑动窗口的不同元素个数可以用map求(无序的话用inordered_map更好)。

    class Solution {
    public:
        int subarraysWithKDistinct(vector<int>& A, int K) {
            if (K > A.size()||K==0)
                return 0;int *min_k = new int[A.size()], *min_k_1 = new int[A.size()];
            cal_min(A,min_k,A.size(),K);     //计算min_k
            cal_min(A, min_k_1, A.size(), K + 1);  //计算min_k_1
            int ans = 0;
            for (int i = 0;i < A.size();i++) {
                if (min_k_1[i] + min_k[i] == -2)    //如果都未更新,则i起始的子数组不同元素个数一定小于K
                    continue;
                else if(min_k_1[i]!=-1)         //min_k_1更新
                    ans += min_k_1[i] - min_k[i];  
                else ans += A.size() - min_k[i];    //min_k_1未更新,min_k更新,最后一个元素依然长度为K
            }
            return ans;
        }
        void cal_min(vector<int>& A,int *Min,int len,int K) {
            map<int, int> mp;
            memset(Min, -1, 4 * len);
            for (int i = 0;i < K;i++)
                mp[A[i]]++;
            int l = 0, r = K - 1;
            while (r < A.size()) {
                while (mp.size() == K) {
                    Min[l] = r;
                    mp[A[l]]--;
                    if (mp[A[l]] == 0)
                        mp.erase(A[l]);
                    l++;
                }
                r++;
                if (r<A.size())
                    mp[A[r]]++;
            }
        }
    };
    

      

  • 相关阅读:
    Javascript面向对象(三):非构造函数的继承
    Javascript面向对象(二):构造函数的继承
    Javascript 面向对象(一):封装
    .NET面试题系列[12]
    .NET面试题系列[11]
    .NET面试题系列[10]
    .NET面试题系列[9]
    .NET面试题系列[8]
    .NET面试题系列[7]
    .NET面试题系列[6]
  • 原文地址:https://www.cnblogs.com/dlutjwh/p/10730160.html
Copyright © 2011-2022 走看看