classSolution: defcountCompleteSubarrays(self, nums: List[int]) -> int: n = len(nums) cnt = len(set(nums)) res = 0 for i inrange(n): se = set() for j inrange(i,n): if nums[j] notin se: se.add(nums[j]) iflen(se) == cnt: res+=1 return res
classSolution: defcountCompleteSubarrays(self, nums: List[int]) -> int: l,r = 0,0 n = len(nums) m = len(set(nums)) res = 0 diff = 0 d = dict() while l < n: while r < n and diff < m: d[nums[r]] = d.get(nums[r],0) + 1 if d[nums[r]] == 1: diff +=1 r += 1 # 跳出来了 if diff < m: break res += n - r + 1 d[nums[l]] -= 1 if d[nums[l]] == 0: diff -= 1 l+=1 return res
classSolution: defcountCompleteSubarrays(self, nums: List[int]) -> int: n = len(nums) le = len(set(nums)) ans = 0 for i inrange(n): s = set() for j inrange(i,n): s.add(nums[j]) iflen(s) == le: ans += n - j break return ans
滑动窗口
固定右端点,尽可能大的把左端点移动,答案的贡献个数就是左边移动的长度
python
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution: defcountCompleteSubarrays(self, nums: List[int]) -> int: n = len(nums) l,ans = 0,0 le = len(set(nums)) c = Counter() for r inrange(n): c[nums[r]] += 1 while c[nums[l]] > 1: c[nums[l]] -= 1 l += 1 iflen(c) == le: ans += l + 1 return ans
classSolution: defcountCompleteSubarrays(self, nums: List[int]) -> int: m = len(set(nums)) cnt = Counter() ans = left = 0 for v in nums: # 枚举子数组右端点 v=nums[i] ans += left # 子数组左端点 < left 的都是合法的 cnt[v] += 1 whilelen(cnt) == m: ans += 1# 子数组左端点等于 left 是合法的 x = nums[left] cnt[x] -= 1 if cnt[x] == 0: del cnt[x] left += 1 return ans