classSolution: defcountCompleteSubarrays(self, nums: List[int]) -> int: m = len(set(nums)) cnt = Counter() ans = left = 0 for v in nums: # 枚举子数组右端点 v=nums[i] cnt[v] += 1 whilelen(cnt) == m: x = nums[left] cnt[x] -= 1 if cnt[x] == 0: del cnt[x] left += 1 ans += left # 子数组左端点 < left 的都是合法的 return ans
[sol-Java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution { publicintcountCompleteSubarrays(int[] nums) { varset=newHashSet<Integer>(); for (int x : nums) set.add(x); intm= set.size(); varcnt=newHashMap<Integer, Integer>(); intans=0, left = 0; for (int v : nums) { // 枚举子数组右端点 v=nums[i] cnt.merge(v, 1, Integer::sum); while (cnt.size() == m) { intx= nums[left++]; if (cnt.merge(x, -1, Integer::sum) == 0) cnt.remove(x); } ans += left; // 子数组左端点 < left 的都是合法的 } return ans; } }
[sol-C++]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
classSolution { public: intcountCompleteSubarrays(vector<int> &nums){ int m = unordered_set<int>(nums.begin(), nums.end()).size(); unordered_map<int, int> cnt; int ans = 0, left = 0; for (int v: nums) { // 枚举子数组右端点 v=nums[i] cnt[v]++; while (cnt.size() == m) { int x = nums[left++]; if (--cnt[x] == 0) cnt.erase(x); } ans += left; // 子数组左端点 < left 的都是合法的 } return ans; } };
funccountCompleteSubarrays(nums []int) (ans int) { set := map[int]struct{}{} for _, v := range nums { set[v] = struct{}{} } m := len(set)
cnt := map[int]int{} left := 0 for _, v := range nums { // 枚举子数组右端点 v=nums[i] cnt[v]++ forlen(cnt) == m { x := nums[left] cnt[x]-- if cnt[x] == 0 { delete(cnt, x) } left++ } ans += left // 子数组左端点 < left 的都是合法的 } return }
[sol-JavaScript]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
var countCompleteSubarrays = function (nums) { const m = newSet(nums).size; let cnt = newMap(); let ans = 0, left = 0; for (const v of nums) { // 枚举子数组右端点 v=nums[i] cnt.set(v, (cnt.get(v) ?? 0) + 1); while (cnt.size === m) { const x = nums[left++]; cnt.set(x, cnt.get(x) - 1); if (cnt.get(x) === 0) cnt.delete(x); } ans += left; // 子数组左端点 < left 的都是合法的 } return ans; };