题目描述

✅ 1343. 大小为 K 且平均值大于等于阈值的子数组数目

image-20260928224249636

题意分析

统计长度恰好为 k、平均值不小于 threshold 的连续子数组数量。不同起点算不同子数组,即使它们的元素完全相同,也要分别计数。

解法:定长滑动窗口

核心思路

[!blue]

题目保证 $k>0$,所以平均值条件 sum / k >= threshold 等价于 sum >= k * threshold。先计算总和门槛 target,之后只做整数比较,既不需要浮点数,也不会发生除法截断。

相邻两个长度为 $k$ 的窗口共享中间 $k-1$ 项,只需加入新的右端、减去离开的左端,就能得到新窗口和。遍历到 i 时先加上 arr[i];若 i >= k,此时临时多出一项,减去 arr[i - k]。更新后,sum 始终是截至 i 的最近至多 $k$ 个元素之和。

只有 i >= k - 1 才形成完整窗口 [i - k + 1, i],此时满足门槛就将 answer 加一。每个合法窗口都有唯一的右端点,依次检查这些右端点便恰好覆盖全部 $n-k+1$ 个窗口,不重不漏。

解题步骤

  • 预先计算总和门槛。
  • 每步加入右端,下标达到 k 后移出 i−k。
  • 从 i=k−1 的首个完整窗口开始检查。
  • 扫描结束后返回累计数量。

代码实现

class Solution {
    public int numOfSubarrays(int[] arr, int k, int threshold) {

        int target = k * threshold;
        int sum = 0;
        int answer = 0;

        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];

            // 满窗之后才移出旧左端,移出的下标是 i 减 k。
            if (i >= k) {
                sum -= arr[i - k];
            }

            // 首个完整窗口从第 k 个元素形成,等于门槛也计数。
            if (i >= k - 1 && sum >= target) {
                answer++;
            }
        }

        return answer;
    }
}
func numOfSubarrays(arr []int, k int, threshold int) int {

    target := k * threshold
    sum := 0
    answer := 0

    for i := 0; i < len(arr); i++ {
        sum += arr[i]

        // 满窗之后才移出旧左端,移出的下标是 i 减 k。
        if i >= k {
            sum -= arr[i-k]
        }

        // 首个完整窗口从第 k 个元素形成,等于门槛也计数。
        if i >= k-1 && sum >= target {
            answer++
        }
    }

    return answer
}

复杂度分析

  • 时间复杂度:$O(n)$,每个元素最多加入和移出窗口各一次。
  • 空间复杂度:$O(1)$,不保存前缀数组。

关键点总结

[!green]

  • 首次满窗与首次移出相差一个位置。
  • 平均值恰好等于门槛也计入。
  • k = 1 时逐个判断元素,k = n 时只判断整个数组,都由同一循环覆盖。
  • 题面中 $n\le10^5$,元素和阈值不超过 $10^4$,窗口和及 k * threshold 都不超过 $10^9$。

易错点总结

[!yellow]

  • 统计放在移出之前,会用到临时 k+1 项之和。
  • 把平均值门槛直接当和门槛,会放宽条件。
  • k 等于数组长度时仍有一个窗口,不能提前返回零。

相似题目

题目 难度 关联与区别
643. 子数组最大平均数 I 简单 固定窗口求和相同,本题统计达到平均值阈值的窗口,原题只取最大平均值。
209. 长度最小的子数组 中等 本题窗口长度固定,可把平均值阈值乘k转成和阈值;原题窗口长度可变并求最短。
转载与许可
作者
链接 https://hgnulb.github.io/blog/2026/25029932
许可 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!