問題背景
給你一個由 正 整數組成的數組 n u m s nums nums。
如果數組中的某個子數組滿足下述條件,則稱之為 完全子數組 :
- 子數組中 不同 元素的數目等于整個數組不同元素的數目。
返回數組中 完全子數組 的數目。
子數組 是數組中的一個連續非空序列。
數據約束
- 1 ≤ n u m s . l e n g t h ≤ 1000 1 \le nums.length \le 1000 1≤nums.length≤1000
- 1 ≤ n u m s [ i ] ≤ 2000 1 \le nums[i] \le 2000 1≤nums[i]≤2000
解題過程
子數組越長,包含的元素種類越多,越有可能符合條件,滿足單調性的要求,可以滑窗。
累計答案的時候需要注意,整個數組中元素的數目不會小于子數組中元素的數目。
出現某個范圍內的元素已經包含了所有種類,這時候擴展端點得到的所有子數組都是符合條件的。
其中,如果在內層循環中進行統計,那么右端點可以選擇從當前位置到數組末尾的所有所有位置;如果在內層循環結束時進行統計,那么左端點可以選擇從零位置開始到當前位置之前的所有位置。
具體實現
class Solution {public int countCompleteSubarrays(int[] nums) {int[] count = new int[2010];Set<Integer> set = new HashSet<>();for (int num : nums) {set.add(num);}int diff = set.size();int res = 0;int n = nums.length;for (int left = 0, right = 0; right < n; right++) {if (count[nums[right]]++ == 0) {diff--;}while (diff == 0) {if(--count[nums[left++]] == 0) {diff++;}// 在內層循環中統計答案,固定左端點得到的所有子數組都是符合條件的res += n - right;}// 在內層循環結束時統計答案,固定右端點得到的所有子數組都是符合條件的// res += left;}return res;}
}