题目介绍
问题描述
小M有一个由正整数组成的数组 nums,她想知道其中有多少子数组可以被称为「好子数组」。一个子数组被称为「好子数组」是指它包含的不同整数个数恰好为 k。
例如,对于数组 [1, 2, 3, 1, 2],其中包含 3 个不同的整数:1、2 和 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
}