给你一个整数数组 nums 和一个整数 k ,请你返回 nums 中 好 子数组的数目。
一个子数组 arr 如果有 至少 k 对下标 (i, j) 满足 i < j 且 arr[i] == arr[j] ,那么称它是一个 好 子数组。
子数组 是原数组中一段连续 非空 的元素序列。
示例 1:
输入:nums = [1,1,1,1,1], k = 10
输出:1
解释:唯一的好子数组是这个数组本身。
示例 2:
输入:nums = [3,1,4,3,2,2,4], k = 2
输出:4
解释:总共有 4 个不同的好子数组:
- [3,1,4,3,2,2] 有 2 对。
- [3,1,4,3,2,2,4] 有 3 对。
- [1,4,3,2,2,4] 有 2 对。
- [4,3,2,2,4] 有 2 对。
提示:
1 <= nums.length <= 10 5 ^5 5
1 <= nums[i], k <= 10 9 ^9 9
滑动窗口,窗口内是一个好子数组时,加上窗口左边的元素也是好子数组:
class Solution {
public:long long countGood(vector<int>& nums, int k) {long long ans = 0;unordered_map<int, int> cnt;int left = 0;int curGood = 0;for (int i = 0; i < nums.size(); ++i) {// 当窗口内新增一个元素m时,相等元素的对数会增加cnt[m]对curGood += cnt[nums[i]];++cnt[nums[i]];while (curGood >= k) {--cnt[nums[left]];// 当窗口内减少一个元素m时,相等元素的对数会减少cnt[m]-1对curGood -= cnt[nums[left]];++left;}ans += left;}return ans;}
};
如果输入数组nums的大小为n,nums中的数字种类数为m,则此算法时间复杂度为O(n),空间复杂度为O(m)。