好子数组的计数 | 豆包MarsCode AI刷题

68 阅读3分钟

题目介绍

问题描述

小M有一个由正整数组成的数组 nums,她想知道其中有多少子数组可以被称为「好子数组」。一个子数组被称为「好子数组」是指它包含的不同整数个数恰好为 k

例如,对于数组 [1, 2, 3, 1, 2],其中包含 3 个不同的整数:12 和 3

子数组指的是数组的连续部分。小M需要找出所有满足条件的子数组,并计算它们的数量。


测试样例

样例1:

输入:nums = [1, 2, 1, 2, 3],k = 2
输出:7

样例2:

输入:nums = [1, 2, 1, 3, 2],k = 3
输出:5

样例3:

输入:nums = [1, 1, 1, 1],k = 1
输出:10

思路描述

初步思路

首先存在一个正整数的数组,我们需要对这个数组的子数组进行判断是否满足好子数组的定义,好子数组是该数组它包含的不同整数个数恰好为 k那么就满足条件,我们需要注意一点,子数组是指的的是数组中连续的子部分,一定要注意好这个条件!!返回最终子数组的数量就行。

深入思路

对于数组还是老套路进行遍历,在遍历的过程中,我们如何访问子数组了,很显然我们需要在这里用到双指针的思路来完成子数组的遍历。对于数组,有一个索引为i,表示数组的开头,然后从左往右依次设计一个额外的指针索引j来模拟子数组的出现。那么按照i和j的移动,我们可以得到所有的子数组的情况,同时这里要注意一个重要的关键点:一个数据本身也是自己的子数组,所有要算上本身,当时自己没有考虑到,卡了很久,其实就是没有理解这个概念,还好豆包刷题是可以看到被卡的样例的,要是acm模式下或者oj下不知道要花多少时间了。然后就是对于得到的子数组,如何知道这个子数组中的元素为k了,如何统计次数了,这里我们想到了一个map映射,为啥要用他了??其实map不仅可以管理一个映射关系,比如元素和其出现的次数,同时也可以在一定的程序上进行去重,2个元素会变成一个元素出现2次(其实也可以用set数据结构),那么我们在处理子数组的时候,就可以用一个map数据结构来同步处理,这样每一次得到子数组的时候也就可以得到map数据,然后再判断map的数量是否和k相等,如果相等那就满足条件,统计次数并且返回。

代码如下

代码

bool isGood(unordered_map<int, int> myMap, vector<int> nums, int i) {
    if (myMap.size() == i) return true;
    return false;
}


int solution(std::vector<int> nums, int k) {
    int n = nums.size();
    int res = 0;
    for (int i = 0; i < n; i++) {
        unordered_map<int, int> myMap;
        myMap[nums[i]]++;
        //先检测自己是否合格,一开始忽略了。自己也算是一个子数组
        if (isGood(myMap, nums, k)) {
            res++;
        }
        //增加数组
        for (int j = i + 1; j < n; j++) {
            myMap[nums[j]]++;
            if (isGood(myMap, nums, k)) {
                res++;
            }
        }
    }
    return res; // Placeholder return
}