|
| 1 | +--- |
| 2 | +title: 2799.统计完全子数组的数目:滑动窗口(哈希表) |
| 3 | +date: 2025-04-24 23:24:12 |
| 4 | +tags: [题解, LeetCode, 中等, 数组, 哈希表, set, map, 滑动窗口] |
| 5 | +categories: [题解, LeetCode] |
| 6 | +--- |
| 7 | + |
| 8 | +# 【LetMeFly】2799.统计完全子数组的数目:滑动窗口(哈希表) |
| 9 | + |
| 10 | +力扣题目链接:[https://leetcode.cn/problems/count-complete-subarrays-in-an-array/](https://leetcode.cn/problems/count-complete-subarrays-in-an-array/) |
| 11 | + |
| 12 | +<p>给你一个由 <strong>正</strong> 整数组成的数组 <code>nums</code> 。</p> |
| 13 | + |
| 14 | +<p>如果数组中的某个子数组满足下述条件,则称之为 <strong>完全子数组</strong> :</p> |
| 15 | + |
| 16 | +<ul> |
| 17 | + <li>子数组中 <strong>不同</strong> 元素的数目等于整个数组不同元素的数目。</li> |
| 18 | +</ul> |
| 19 | + |
| 20 | +<p>返回数组中 <strong>完全子数组</strong> 的数目。</p> |
| 21 | + |
| 22 | +<p><strong>子数组</strong> 是数组中的一个连续非空序列。</p> |
| 23 | + |
| 24 | +<p> </p> |
| 25 | + |
| 26 | +<p><strong>示例 1:</strong></p> |
| 27 | + |
| 28 | +<pre><strong>输入:</strong>nums = [1,3,1,2,2] |
| 29 | +<strong>输出:</strong>4 |
| 30 | +<strong>解释:</strong>完全子数组有:[1,3,1,2]、[1,3,1,2,2]、[3,1,2] 和 [3,1,2,2] 。 |
| 31 | +</pre> |
| 32 | + |
| 33 | +<p><strong>示例 2:</strong></p> |
| 34 | + |
| 35 | +<pre><strong>输入:</strong>nums = [5,5,5,5] |
| 36 | +<strong>输出:</strong>10 |
| 37 | +<strong>解释:</strong>数组仅由整数 5 组成,所以任意子数组都满足完全子数组的条件。子数组的总数为 10 。 |
| 38 | +</pre> |
| 39 | + |
| 40 | +<p> </p> |
| 41 | + |
| 42 | +<p><strong>提示:</strong></p> |
| 43 | + |
| 44 | +<ul> |
| 45 | + <li><code>1 <= nums.length <= 1000</code></li> |
| 46 | + <li><code>1 <= nums[i] <= 2000</code></li> |
| 47 | +</ul> |
| 48 | + |
| 49 | + |
| 50 | + |
| 51 | +## 解题方法:滑动窗口 |
| 52 | + |
| 53 | +首先使用一个哈希表统计数组中出现了多少种的元素(记为`allType`)。 |
| 54 | + |
| 55 | +接着再使用一个哈希表,统计窗口中每个元素出现多少次。 |
| 56 | + |
| 57 | +数组中的元素依次加入窗口中,当`窗口中元素种类数为allType`并且`窗口中第一个元素出现次数不为1`时,左移窗口左指针。 |
| 58 | + |
| 59 | +这样,就保证了每次窗口右指针确定时,左指针指向位置为最后一个“窗口合法”的位置(或0)。 |
| 60 | + |
| 61 | ++ 时间复杂度$O(len(nums))$ |
| 62 | ++ 空间复杂度$O(len(nums))$ |
| 63 | + |
| 64 | +### AC代码 |
| 65 | + |
| 66 | +#### C++ |
| 67 | + |
| 68 | +```cpp |
| 69 | +/* |
| 70 | + * @Author: LetMeFly |
| 71 | + * @Date: 2025-04-24 22:47:03 |
| 72 | + * @LastEditors: LetMeFly.xyz |
| 73 | + * @LastEditTime: 2025-04-24 23:05:27 |
| 74 | + * @Description: AC,36.08%,63.38% |
| 75 | + */ |
| 76 | +class Solution { |
| 77 | +public: |
| 78 | + int countCompleteSubarrays(vector<int>& nums) { |
| 79 | + unordered_set<int> visited; |
| 80 | + for (int t : nums) { |
| 81 | + visited.insert(t); |
| 82 | + } |
| 83 | + int allType = visited.size(); |
| 84 | + unordered_map<int, int> times; |
| 85 | + int ans = 0; |
| 86 | + for (int l = 0, r = 0; r < nums.size(); r++) { |
| 87 | + times[nums[r]]++; |
| 88 | + while (times.size() == allType && times[nums[l]] > 1) { |
| 89 | + times[nums[l++]]--; |
| 90 | + } |
| 91 | + if (times.size() == allType) { |
| 92 | + ans += l + 1; |
| 93 | + } |
| 94 | + } |
| 95 | + return ans; |
| 96 | + } |
| 97 | +}; |
| 98 | + |
| 99 | +``` |
| 100 | +
|
| 101 | +#### Python |
| 102 | +
|
| 103 | +```python |
| 104 | +''' |
| 105 | +Author: LetMeFly |
| 106 | +Date: 2025-04-24 22:47:44 |
| 107 | +LastEditors: LetMeFly.xyz |
| 108 | +LastEditTime: 2025-04-24 23:10:14 |
| 109 | +Description: AC,60.65%,29.08% |
| 110 | +''' |
| 111 | +from typing import List |
| 112 | +from collections import defaultdict |
| 113 | +
|
| 114 | +class Solution: |
| 115 | + def countCompleteSubarrays(self, nums: List[int]) -> int: |
| 116 | + allType = len(set(nums)) |
| 117 | + times = defaultdict(int) |
| 118 | + l = ans = 0 |
| 119 | + for r in range(len(nums)): |
| 120 | + times[nums[r]] += 1 |
| 121 | + while len(times) == allType and times[nums[l]] > 1: |
| 122 | + times[nums[l]] -= 1 |
| 123 | + l += 1 |
| 124 | + if len(times) == allType: |
| 125 | + ans += l + 1 |
| 126 | + return ans |
| 127 | +``` |
| 128 | + |
| 129 | +#### Java |
| 130 | + |
| 131 | +```java |
| 132 | +/* |
| 133 | + * @Author: LetMeFly |
| 134 | + * @Date: 2025-04-24 22:47:48 |
| 135 | + * @LastEditors: LetMeFly.xyz |
| 136 | + * @LastEditTime: 2025-04-24 23:18:36 |
| 137 | + * @Description: AC,65.83%,85.83% |
| 138 | + */ |
| 139 | +import java.util.Set; |
| 140 | +import java.util.Map; |
| 141 | +import java.util.HashSet; |
| 142 | +import java.util.HashMap; |
| 143 | + |
| 144 | +class Solution { |
| 145 | + public int countCompleteSubarrays(int[] nums) { |
| 146 | + Set<Integer> se = new HashSet<>(); |
| 147 | + for (int t : nums) { |
| 148 | + se.add(t); |
| 149 | + } |
| 150 | + int allType = se.size(); |
| 151 | + Map<Integer, Integer> times = new HashMap<>(); |
| 152 | + int ans = 0; |
| 153 | + int l = 0; |
| 154 | + for (int t : nums) { |
| 155 | + times.merge(t, 1, Integer::sum); |
| 156 | + while (times.size() == allType && times.get(nums[l]) > 1) { |
| 157 | + times.merge(nums[l++], -1, Integer::sum); |
| 158 | + } |
| 159 | + if (times.size() == allType) { |
| 160 | + ans += l + 1; |
| 161 | + } |
| 162 | + } |
| 163 | + return ans; |
| 164 | + } |
| 165 | +} |
| 166 | +``` |
| 167 | + |
| 168 | +#### Go |
| 169 | + |
| 170 | +```go |
| 171 | +/* |
| 172 | + * @Author: LetMeFly |
| 173 | + * @Date: 2025-04-24 22:47:30 |
| 174 | + * @LastEditors: LetMeFly.xyz |
| 175 | + * @LastEditTime: 2025-04-24 23:23:21 |
| 176 | + * @Description: AC,32.53%,40.96% |
| 177 | + */ |
| 178 | +package main |
| 179 | + |
| 180 | +func countCompleteSubarrays(nums []int) (ans int) { |
| 181 | + visited := map[int]bool{} |
| 182 | + for _, t := range nums { |
| 183 | + visited[t] = true |
| 184 | + } |
| 185 | + allType := len(visited) |
| 186 | + times := map[int]int{} |
| 187 | + l := 0 |
| 188 | + for _, t := range nums { |
| 189 | + times[t]++ |
| 190 | + for len(times) == allType && times[nums[l]] > 1 { |
| 191 | + times[nums[l]]-- |
| 192 | + l++ |
| 193 | + } |
| 194 | + if len(times) == allType { |
| 195 | + ans += l + 1 |
| 196 | + } |
| 197 | + } |
| 198 | + return |
| 199 | +} |
| 200 | +``` |
| 201 | + |
| 202 | +> 同步发文于[CSDN](https://letmefly.blog.csdn.net/article/details/147494871)和我的[个人博客](https://blog.letmefly.xyz/),原创不易,转载经作者同意后请附上[原文链接](https://blog.letmefly.xyz/2025/04/24/LeetCode%202799.%E7%BB%9F%E8%AE%A1%E5%AE%8C%E5%85%A8%E5%AD%90%E6%95%B0%E7%BB%84%E7%9A%84%E6%95%B0%E7%9B%AE/)哦~ |
| 203 | +> |
| 204 | +> 千篇源码题解[已开源](https://github.com/LetMeFly666/LeetCode) |
0 commit comments