Solution: Count Subarrays With Score Less Than K
Let's solve the Count Subarrays With Score Less Than K problem using the Sliding Window pattern.
We'll cover the following
Statement
An array score is defined as the sum of the array elements multiplied by its length. For example, if the array is
Given an array of positive integers, nums
, and a positive integer k
, count and return the number of non-empty subarrays of nums
whose score is strictly less than k
.
Note: A subarray is a contiguous sequence of elements within an array.
Constraints:
nums.length
nums[i]
k
Solution
A straightforward way to solve this would be to look at every possible subarray of nums
, calculate its score, and check if it's less than k
. If nums
has n
elements, there are n
becomes large.
Instead of recalculating the sum and score for every possible subarray, a sliding window approach can achieve the result in a single pass. The idea is to maintain a window using two pointers and keep track of a
If the score is less than k
, then not only is the current subarray valid, but all subarrays ending at the current right pointer and starting anywhere within the window are also valid. If the entire window from the left to the right pointer has a valid score, any shorter subarray within that window (as long as it still ends at the right pointer position) will also have a valid score. For example, if the subarray [nums[i], ..., nums[j]]
is valid, then the subarray [nums[i+1], ..., nums[j]]
is also valid (it’s shorter, so its score will be even smaller or the same, and less than k
). The same logic applies to the subarray [nums[i+2], ..., nums[j]]
, [nums[i+3], ..., nums[j]]
, and so on. The count of all such valid subarrays within a subarray can be calculated as:
If the score exceeds or equals k
, shrink the window from the left by moving the left pointer forward and updating the running sum accordingly. This continues until the current window/subarray score drops below k
.
By repeating this process throughout the array, i.e., expanding the second pointer and adjusting the first, the algorithm counts all valid subarrays efficiently, without checking each one individually.
Let's look at the algorithm steps:
Initialize the variables:
Set
result = 0
to accumulate the total count of valid subarrays.Set
runningSum = 0
to keep a running sum of elements in the current window.Set
left = 0
as the start index of the sliding window.
Use the
right
pointer to iterate over thenums
list. In each iteration:Add the number at
nums[right]
torunningSum
. This effectively expands the window to the right.Compute the current window’s score as
score = runningSum * (right - left + 1)
. Here,(right - left + 1)
is the window’s length. Multiplying byrunningSum
gives the score of the subarray fromleft
toright
.If the
score
exceedsk
, shrink the window. Whilescore >= k
:Subtract the number at
nums[left]
fromrunningSum
. This removes the leftmost element from the window.Increment
left
by 1. This moves the left boundary of the window to the right.Recompute the
score
as bothrunningSum
and window length have changed.
Once the
score
is less thank
, count all valid subarrays ending atright
, i.e., add(right - left + 1)
to theresult
.
Once the entire
nums
list has been traversed, return theresult
with the total number of subarrays whose score is less thank
.
The slides below help to understand the solution in a better way.
Level up your interview prep. Join Educative to access 70+ hands-on prep courses.