给你一个由 正 整数组成的数组 nums
。
如果数组中的某个子数组满足下述条件,则称之为 完全子数组 :
- 子数组中 不同 元素的数目等于整个数组不同元素的数目。
返回数组中 完全子数组 的数目。
子数组 是数组中的一个连续非空序列。
示例 1:
输入:nums = [1,3,1,2,2] 输出:4 解释:完全子数组有:[1,3,1,2]、[1,3,1,2,2]、[3,1,2] 和 [3,1,2,2] 。
示例 2:
输入:nums = [5,5,5,5] 输出:10 解释:数组仅由整数 5 组成,所以任意子数组都满足完全子数组的条件。子数组的总数为 10 。
提示:
1 <= nums.length <= 1000
1 <= nums[i] <= 2000
提示 1
Let’s say k is the number of distinct elements in the array. Our goal is to find the number of subarrays with k distinct elements.
提示 2
Since the constraints are small, you can check every subarray.
解法1:Brute Force / 暴力匹配算法 / 朴素匹配算法 / 穷举法 + 固定长度滑动窗口
class Solution {
public int countCompleteSubarrays(int[] nums) {
int n = nums.length;
int ans = 0;
Set<Integer> set = new HashSet<>();
for (int i = 0; i < n; i++) {
set.add(nums[i]);
}
int k = set.size();
for (int i = k; i < n; i++) {
Map<Integer, Integer> window = new HashMap<>();
int left = 0;
int right = 0;
while (right < n) {
window.merge(nums[right], 1, Integer::sum);
while (right - left + 1 == i) {
if (window.size() == k) {
ans++;
}
if (window.merge(nums[left], -1, Integer::sum) == 0) {
window.remove(nums[left]);
}
left++;
}
right++;
}
}
// 当窗口长度为n时,一定是一个完全子数组,单独加上1
return ans + 1;
}
}
复杂度分析
- 时间复杂度:O(n^2),n 是 数组nums 的长度。写了个二重循环,所以总的时间复杂度为 O(n + n^2) = O(n^2)。
- 空间复杂度:O(k),k为nums的整数集的长度。
解法2:不定长滑动窗口
class Solution {
public int countCompleteSubarrays(int[] nums) {
int n = nums.length;
int ans = 0;
Set<Integer> set = new HashSet<>();
for (int i = 0; i < n; i++) {
set.add(nums[i]);
}
int k = set.size();
Map<Integer, Integer> window = new HashMap<>();
int left = 0;
int right = 0;
while (right < n) {
window.merge(nums[right], 1, Integer::sum);
if (window.size() == k) {
// 右边界固定,找到最大的符合要求的左边界(窗口内整数种类为k)
while (window.get(nums[left]) > 1) {
window.merge(nums[left], -1, Integer::sum);
left++;
}
// 此时 window.get(nums[left]) == 1,此时left为最大的符合要求的左边界
// 如果将窗口扩大,左边界为[0,..., left]中的任意一点都符合要求
// 完全子数组:[0,..., right],[1,..., right],..., [left,..., right]
ans += left + 1;
}
right++;
}
return ans;
}
}
复杂度分析
- 时间复杂度:O(n),n 是 数组nums 的长度。总的时间复杂度为 O(n + n) = O(n)。
- 空间复杂度:O(k),k为nums的整数集的长度。