Your are given an array of positive integers nums. Count and print the number of (contiguous) subarrays where the product of all the elements in the subarray is less than k.
For original task refer to leetcode
Example 1:
Input: nums = [10, 5, 2, 6], k = 100
Output: 8
Explanation: The 8 subarrays that have product less than 100 are: [10], [5], [2], [6], [10, 5], [5, 2], [2, 6], [5, 2, 6].
Note that [10, 5, 2] is not included as the product of 100 is not strictly less than k.
Constraints:
- 0 < nums.length <= 50000.
- 0 < nums[i] < 1000.
- 0 <= k < 10^6
Approach
We can apply sliding window type of approach to solve this problem. Where we create a virtual window that contains the range of values that whose product are less then a given k
. Every time when we slide the window to one-step to the right, we check and stabilize the table by shifting the left-side border (if necessary). Summary of range size in every step gives us expected result.
- initilize left and right borders of the window
product
initialized as 1 (thats what usually used for production aggregation)productCount
initialized as a 0 (this is where we aggregate summary of possible variations)- run the cycle for the whole array
- multiply the next coming value to the
product
aggregator - if the
product
aggregator is over the givenk
limit, then start subtracting left-most elements of the window (by shifting the left border to the right) - aggregate current is of the window
- multiply the next coming value to the
Time Complexity: O(N), where N is the number of elements in the array.
Space Complexity: O(1), only operational variables are used.
Solution (Java)
class Solution {
public int numSubarrayProductLessThanK(int[] nums, int k) {
int left = 0, right = 0;
int product = 1;
int prodCount = 0;
while (right < nums.length) {
product *= nums[right];
while (left <= right && product >= k) {
product = product / nums[left];
left++;
}
prodCount += right - left + 1;
right++;
}
return prodCount;
}
}