给你一个整数数组 nums 和一个整数 k ,请你返回 nums 中 好 子数组的数目。
一个子数组 arr 如果有 至少 k 对下标 (i, j) 满足 i < j 且 arr[i] == arr[j] ,那么称它是一个 好 子数组。
子数组 是原数组中一段连续 非空 的元素序列。
https://leetcode.cn/problems/count-the-number-of-good-subarrays/
- 滑动窗口两种形式:
while
或for
- 数学归纳:{1,1,1,1}的好子数组为:3 + 2 + 1
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
*/
package com.huawei.prac;
import java.util.HashMap;
import java.util.Map;
class Solution8th {
public static void main(String[] args) {
int[] nums = {3, 1, 4, 3, 2, 4, 2, 4};
int k = 2;
System.out.println(countGood(nums, k));
int[] nums1 = {1, 1, 1, 1, 1};
int k1 = 10;
System.out.println(countGood(nums1, k1));
}
/**
* 2537. 统计好子数组的数目[滑动窗口 + hashmap]
* 若不满足条件则 right++,若满足条件则 left++
*
* @param nums 整数数组
* @param k 整数
* @return 好 子数组的数量
*/
public static long countGood(int[] nums, int k) {
long count = 0;
int left = 0;
int right = 0;
Map<Integer, Integer> map = new HashMap<>();
map.put(nums[right], 1);
int countTmp = 0;
while (right < nums.length && left < nums.length) {
if (countTmp >= k) {
count += nums.length - right;
map.computeIfPresent(nums[left], (key, oldV) -> oldV - 1);
countTmp -= map.get(nums[left]);
left++;
} else {
right++;
if (right < nums.length) {
map.merge(nums[right], 1, (oldV, newV) -> oldV + 1);
countTmp += map.get(nums[right]) - 1;
}
}
}
return count;
}
}