力扣992.K个不同整数的子数组-C语言实现

题目

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

(例如,[1,2,3,1,2] 中有 3 个不同的整数:1,2,以及 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 <= A.length <= 20000
1 <= A[i] <= A.length
1 <= K <= A.length

解题

我们要求的是在数组A中恰好是由k种整数组成的连续子数组的个数。
解析:
k种整数,所以至少长度是k
要求连续

这种要求感觉上可以使用双指针
从头开始遍历,左标记为left,右标记为right,
我们通过双指针经常得到的是最多最大之类的题目,这里是恰好等于k个,所以转换一下就是用最大k个不同整数的子数组个数减去最大k-1不同整数的子数组的个数就可以得到。

模板:

int subarraysWithKDistinct(int* A, int ASize, int K){
    
    
  
}

题解链接-作者:LeetCode-Solution

int subarraysWithKDistinct(int* A, int ASize, int K) {
    
    
    int num1[ASize + 1], num2[ASize + 1];
    memset(num1, 0, sizeof(int) * (ASize + 1));
    memset(num2, 0, sizeof(int) * (ASize + 1));
    int tot1 = 0, tot2 = 0;
    int left1 = 0, left2 = 0, right = 0;
    int ret = 0;
    while (right < ASize) {
    
    
        if (!num1[A[right]]) {
    
    
            tot1++;
        }
        num1[A[right]]++;
        if (!num2[A[right]]) {
    
    
            tot2++;
        }
        num2[A[right]]++;
        while (tot1 > K) {
    
    
            num1[A[left1]]--;
            if (!num1[A[left1]]) {
    
    
                tot1--;
            }
            left1++;
        }
        while (tot2 > K - 1) {
    
    
            num2[A[left2]]--;
            if (!num2[A[left2]]) {
    
    
                tot2--;
            }
            left2++;
        }
        ret += left2 - left1;
        right++;
    }
    return ret;
}

猜你喜欢

转载自blog.csdn.net/qq_44922487/article/details/113765557
今日推荐