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:
1≤ nums.length≤103 1≤ nums[i]≤103 1≤ k≤105
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 = 0to accumulate the total count of valid subarrays.Set
runningSum = 0to keep a running sum of elements in the current window.Set
left = 0as the start index of the sliding window.
Use the
rightpointer to iterate over thenumslist. 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 byrunningSumgives the score of the subarray fromlefttoright.If the
scoreexceedsk, shrink the window. Whilescore >= k:Subtract the number at
nums[left]fromrunningSum. This removes the leftmost element from the window.Increment
leftby 1. This moves the left boundary of the window to the right.Recompute the
scoreas bothrunningSumand window length have changed.
Once the
scoreis less thank, count all valid subarrays ending atright, i.e., add(right - left + 1)to theresult.
Once the entire
numslist has been traversed, return theresultwith the total number of subarrays whose score is less thank.
The slides below help to understand the solution in a better way.