You are given an array of integers arr and two integers k and threshold, return the number of sub-arrays of size k and average greater than or equal to threshold.
Example 1:
Input: arr = [2,2,2,2,5,5,5,8], k = 3, threshold = 4
Output: 3Explanation: Sub-arrays [2,5,5],[5,5,5] and [5,5,8] have averages 4, 5 and 6 respectively. All other sub-arrays of size 3 have averages less than 4 (the threshold).
Example 2:
Input: arr = [11,13,17,23,29,31,7,5,2,3], k = 3, threshold = 5
Output: 6Explanation: The first 6 sub-arrays of size 3 have averages greater than 5. Note that averages are not integers.
Constraints:
1 <= k <= arr.length <= 100,0001 <= arr[i] <= 10,0000 <= threshold <= 10,000Before attempting this problem, you should be comfortable with:
For each valid starting position of a subarray of size k, we compute the sum of all elements in that window and check if the average meets the threshold. This approach recalculates the sum from scratch for every window.
l from 0 to n - k.l to l + k - 1.sum / k >= threshold, increment the result counter.Where is the size of the array and is the size of the sub-array.
Instead of recalculating sums from scratch, we precompute prefix sums. The sum of any subarray from index l to r becomes a simple subtraction: prefix[r+1] - prefix[l]. This trades memory for faster subarray sum queries.
prefix[i] holds the sum of elements from index 0 to i-1.k, compute the sum as prefix[r+1] - prefix[l].class Solution:
def numOfSubarrays(self, arr: List[int], k: int, threshold: int) -> int:
prefix_sum = [0] * (len(arr) + 1)
for i in range(len(arr)):
prefix_sum[i + 1] += prefix_sum[i] + arr[i]
res = l = 0
for r in range(k - 1, len(arr)):
sum_ = prefix_sum[r + 1] - prefix_sum[l]
if sum_ / k >= threshold:
res += 1
l += 1
return resWhere is the size of the array and is the size of the sub-array.
We maintain a running sum of the current window. When the window slides, we add the new element entering from the right and remove the element leaving from the left. This gives constant-time updates per window instead of recalculating from scratch.
curSum with the sum of the first k-1 elements.L:L + k - 1 to complete the window.L before moving to the next window.Where is the size of the array and is the size of the sub-array.
A small optimization: instead of dividing the sum by k for each comparison, we multiply the threshold by k once upfront. This converts the average check into a simple sum comparison, avoiding repeated division.
threshold by k to get the target sum.k:Where is the size of the array and is the size of the sub-array.
When computing sum / k in languages like Java, C++, or Go, integer division truncates toward zero. If the sum is 15 and k is 4, 15 / 4 equals 3, not 3.75. This can cause false negatives when the true average meets the threshold but the truncated result does not. Multiplying the threshold by k and comparing sums directly avoids this issue.
A common inefficiency is recalculating the sum for each window from scratch, leading to O(n*k) time complexity. The sliding window technique maintains a running sum, adding the new element and removing the old element in O(1) time per window.
When sliding the window, it is easy to make mistakes with index calculations. Ensure the window always contains exactly k elements. Common errors include starting the right pointer at the wrong index or incorrectly computing when to start shrinking the window from the left.