【LetMeFly】2799.统计完全子数组的数目:滑动窗口(哈希表) 力扣题目链接:https://leetcode.cn/problems/count-complete-subarrays-in-an-array/
给你一个由 正 整数组成的数组 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
解题方法:滑动窗口 首先使用一个哈希表统计数组中出现了多少种的元素(记为allType
)。
接着再使用一个哈希表,统计窗口中每个元素出现多少次。
数组中的元素依次加入窗口中,当窗口中元素种类数为allType
并且窗口中第一个元素出现次数不为1
时,左移窗口左指针。
这样,就保证了每次窗口右指针确定时,左指针指向位置为最后一个“窗口合法”的位置(或0)。
时间复杂度$O(len(nums))$
空间复杂度$O(len(nums))$
AC代码 C++ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution {public : int countCompleteSubarrays (vector<int >& nums) { unordered_set<int > visited; for (int t : nums) { visited.insert (t); } int allType = visited.size (); unordered_map<int , int > times; int ans = 0 ; for (int l = 0 , r = 0 ; r < nums.size (); r++) { times[nums[r]]++; while (times.size () == allType && times[nums[l]] > 1 ) { times[nums[l++]]--; } if (times.size () == allType) { ans += l + 1 ; } } return ans; } };
Python 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ''' Author: LetMeFly Date: 2025-04-24 22:47:44 LastEditors: LetMeFly.xyz LastEditTime: 2025-04-24 23:10:14 Description: AC,60.65%,29.08% ''' from typing import List from collections import defaultdictclass Solution : def countCompleteSubarrays (self, nums: List [int ] ) -> int : allType = len (set (nums)) times = defaultdict(int ) l = ans = 0 for r in range (len (nums)): times[nums[r]] += 1 while len (times) == allType and times[nums[l]] > 1 : times[nums[l]] -= 1 l += 1 if len (times) == allType: ans += l + 1 return ans
Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 import java.util.Set;import java.util.Map;import java.util.HashSet;import java.util.HashMap;class Solution { public int countCompleteSubarrays (int [] nums) { Set<Integer> se = new HashSet <>(); for (int t : nums) { se.add(t); } int allType = se.size(); Map<Integer, Integer> times = new HashMap <>(); int ans = 0 ; int l = 0 ; for (int t : nums) { times.merge(t, 1 , Integer::sum); while (times.size() == allType && times.get(nums[l]) > 1 ) { times.merge(nums[l++], -1 , Integer::sum); } if (times.size() == allType) { ans += l + 1 ; } } return ans; } }
Go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package mainfunc countCompleteSubarrays (nums []int ) (ans int ) { visited := map [int ]bool {} for _, t := range nums { visited[t] = true } allType := len (visited) times := map [int ]int {} l := 0 for _, t := range nums { times[t]++ for len (times) == allType && times[nums[l]] > 1 { times[nums[l]]-- l++ } if len (times) == allType { ans += l + 1 } } return }
同步发文于CSDN 和我的个人博客 ,原创不易,转载经作者同意后请附上原文链接 哦~
千篇源码题解已开源