给你一个由 正 整数组成的数组 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. 以该数组左边界为边界。2. 以该数组右边界为边界。3. 该数组左右边界都不是边界。
固定一遍,向右遍历。可以发现,当固定左边界后,第三种情况一定会在之前的遍历就包含。而第二种情况,则是当前情况的答案数量。
滑动窗口。
class Solution { // 滑动窗口。 // 维护窗口中的数据总是符合题意。 // 可以想到,以当前窗口左边界开始,以当前窗口为子窗口的字数组,共有 len - right 个(len指数组长度,right 指窗口右边界。) public int countCompleteSubarrays(int[] nums) { Set<Integer> set = new HashSet<>(); for (int x : nums) { set.add(x); } int left = 0; int right = 0; int res = 0; int n = set.size(); Map<Integer, Integer> map = new HashMap<>(); while (right < nums.length) { if (map.size() < n) { map.put(nums[right], map.getOrDefault(nums[right], 0) + 1); right++; if (map.size() < n) { continue; } } while (map.size() == n) { res += nums.length - right + 1; if (map.get(nums[left]) == 1) { map.remove(nums[left]); } else { map.put(nums[left], map.get(nums[left]) - 1); } left++; } } return res; } }
标签:力扣,right,map,int,nums,---,数组,6900,left From: https://www.cnblogs.com/allWu/p/17591475.html