713. Subarray Product Less Than K - Explanation
Description
You are given an array of integers nums and an integer k, return the number of contiguous subarrays where the product of all the elements in the subarray is strictly less than k.
Example 1:
Input: nums = [10,5,2,6], k = 100
Output: 8Explanation: 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.
Example 2:
Input: nums = [1,2,3], k = 0
Output: 0Example 3:
Input: nums = [1,1,1], k = 1
Output: 0Constraints:
1 <= nums.length <= 30,0001 <= nums[i] <= 10000 <= k <= 1,000,000
Topics
Prerequisites
Before attempting this problem, you should be comfortable with:
- Sliding Window - The optimal solution uses a variable-size window to track valid subarrays with products below the threshold
- Prefix Sums - The binary search approach converts products to sums using logarithms, requiring prefix sum knowledge
- Binary Search - One solution uses binary search on prefix sums to find valid subarray endpoints
1. Brute Force
Intuition
The most straightforward approach is to check every possible subarray. For each starting index, extend the subarray one element at a time while tracking the running product. If the product stays below k, count it. Once the product reaches or exceeds k, no further extensions from this starting point will work (since all elements are positive, the product only grows).
Algorithm
- Initialize a counter
res = 0. - For each starting index
ifrom0ton - 1:- Set
curProd = 1. - For each ending index
jfromiton - 1:- Multiply
curProdbynums[j]. - If
curProd >= k,breakout of the inner loop. - Otherwise, increment
res.
- Multiply
- Set
- Return
res.
Time & Space Complexity
- Time complexity:
- Space complexity:
2. Binary Search
Intuition
Products grow multiplicatively, which makes binary search tricky with raw values. However, taking logarithms converts products into sums: log(a * b) = log(a) + log(b). This means we can build a prefix sum of logarithms and binary search for the rightmost position where the prefix sum difference is less than log(k). For each starting index, we find how many valid ending positions exist.
Algorithm
- Handle the edge case: if
k <= 1, return0(no positive product can be less than1or less). - Build a prefix sum array of logarithms:
logs[i+1] = logs[i] + log(nums[i]). - For each starting index
i:- Binary search for the smallest index
jwherelogs[j] >= logs[i] + log(k). - The count of valid subarrays starting at
iisj - (i + 1).
- Binary search for the smallest index
- Sum all counts and return.
class Solution:
def numSubarrayProductLessThanK(self, nums: List[int], k: int) -> int:
if k <= 1:
return 0
n = len(nums)
res = 0
logs = [0] * (n + 1)
logK = log(k)
for i in range(n):
logs[i + 1] = logs[i] + log(nums[i])
for i in range(n):
l, r = i + 1, n + 1
while l < r:
mid = (l + r) >> 1
if logs[mid] < logs[i] + logK - 1e-9:
l = mid + 1
else:
r = mid
res += l - (i + 1)
return resTime & Space Complexity
- Time complexity:
- Space complexity:
3. Sliding Window
Intuition
Since all numbers are positive, the product of a subarray increases as we add elements and decreases as we remove them. This monotonic property makes sliding window ideal. We maintain a window [l, r] where the product is less than k. When adding nums[r] causes the product to exceed or equal k, we shrink from the left until the product drops below k again. Each valid window ending at r contributes r - l + 1 new subarrays.
Algorithm
- Initialize
l = 0,product = 1, andres = 0. - For each
rfrom0ton - 1:- Multiply
productbynums[r]. - While
product >= kandl <= r, divideproductbynums[l]and incrementl. - Add
r - l + 1tores(this counts all subarrays ending atrwith product < k).
- Multiply
- Return
res.
Time & Space Complexity
- Time complexity:
- Space complexity:
Common Pitfalls
Forgetting the Edge Case When k <= 1
When k is 0 or 1, no positive product can be less than k. Failing to handle this edge case leads to incorrect results or infinite loops. Always check if k <= 1: return 0 at the start.
Using Strict Less-Than Comparison Incorrectly
The problem asks for products strictly less than k, not less than or equal. Using product <= k instead of product < k will overcount subarrays where the product equals exactly k.
Integer Overflow in Product Calculation
When multiplying elements together, the product can quickly exceed integer bounds. In languages like Java or C++, use long instead of int for the product variable to avoid overflow issues, especially with large arrays.
Sign in to join the discussion