給你一個整數數組 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)。