Number of Sub-arrays of Size K and Average Greater than or Equal to Threshold
Given an array of integers arr and two integers k and threshold, return the number of contiguous subarrays of size k whose average is greater than or equal to threshold. Slide a fixed length window of length k and compare the running sum to k * threshold to avoid division each step.
Constraints
- 1 ≤ arr.length ≤ 105
- 1 ≤ arri ≤ 104
- 1 ≤ k ≤ arr.length
Example
arr = [2, 2, 2, 2, 5, 5, 5, 8], k = 3, threshold = 43Explanation The qualifying windows are [2, 5, 5] → 4, [5, 5, 5] → 5, and [5, 5, 8] → 6.
In plain terms
- Contiguous subarray
- A run of elements sitting right next to each other in the array, with nothing skipped — not just any subset you could pick.
- Threshold
- A minimum cutoff value — the average of a window only counts if it is at or above this number, like a passing grade.
Count windows whose average meets the threshold
Window [2, 2, 2]: avg = 2.0 — below threshold.
What happens in this step
window = [0, 2] (size 3) target = k * threshold = 3 * 4 = 12 sum = 2 + 2 + 2 = 6 avg = 6 / 3 = 2.00 sum (6) is below target (12) — this window does not count.
Steps to visualize
- Place a window of length k and compare its sum to k * threshold.
- If the sum meets the target, increment the answer count.
- Slide one step right: drop the leftmost value, add the new rightmost value.
- Check the sum against the target again after each slide.
- Continue until the window reaches the end of the array.
Walk through the code
Same walkthrough, now with the code. Press Next to move one step and watch which lines run.
Window [2, 2, 2]: avg = 2.0 — below threshold.
What happens in this step
window = [0, 2] (size 3) target = k * threshold = 3 * 4 = 12 sum = 2 + 2 + 2 = 6 avg = 6 / 3 = 2.00 sum (6) is below target (12) — this window does not count.
Solution
function numOfSubarrays(arr, k, threshold) {
if (k <= 0 || k > arr.length) {
throw new Error("k must be between 1 and arr.length");
}
const target = k * threshold;
let windowSum = 0;
for (let i = 0; i < k; i++) {
windowSum += arr[i];
}
let count = windowSum >= target ? 1 : 0;
for (let right = k; right < arr.length; right++) {
const left = right - k;
windowSum += arr[right] - arr[left];
if (windowSum >= target) count++;
}
return count;
}- Time
- O(n)
- Space
- O(1)
Test cases
| Input | Expected | Covers |
|---|---|---|
arr = [2, 2, 2, 2, 5, 5, 5, 8], k = 3, threshold = 4 | 3 | example from the docstring |
arr = [5, 5, 5], k = 3, threshold = 5 | 1 | smallest valid input: k === arr.length |
arr = [1, 5, 2, 9, 3], k = 1, threshold = 4 | 2 | k === 1 counts elements that meet the threshold directly |
arr = [1, 1, 1, 1, 1, 1, 1], k = 2, threshold = 1 | 6 | window must slide across the whole array to count all matches |
arr = [4, 4, 4, 4], k = 2, threshold = 4 | 3 | all identical elements: every window qualifies |
arr = [1, 1, 1, 1], k = 2, threshold = 10 | 0 | no valid answer: nothing meets the threshold |
arr = [11, 13, 17, 23, 29, 31, 7, 5, 2, 3], k = 3, threshold = 5 | 6 | larger, hand-verified case |
arr = [1, 2], k = 5, threshold = 1 | throws | throws when k is larger than the array |