Taro Logo

Subarray Product Less Than K

Medium
Apple logo
Apple
Topics:
ArraysSliding Windows

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.

For example:

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.

Another example:

Input: nums = [1,2,3], k = 0
Output: 0

Constraints:

  • 1 <= nums.length <= 3 * 10^4
  • 1 <= nums[i] <= 1000
  • 0 <= k <= 10^6

Can you provide an efficient algorithm to solve this problem, considering both time and space complexity? What are the edge cases to consider?

Solution


Brute Force Approach

The most straightforward approach is to generate all possible contiguous subarrays and check if the product of their elements is less than k. This involves iterating through all possible start and end indices of the subarrays.

Code (Python):

def numSubarrayProductLessThanK_brute_force(nums, k):
    count = 0
    n = len(nums)
    for i in range(n):
        product = 1
        for j in range(i, n):
            product *= nums[j]
            if product < k:
                count += 1
            else:
                break
    return count

Time Complexity: O(n^2), where n is the length of the input array. This is because we have nested loops to generate all possible subarrays.

Space Complexity: O(1), as we are only using a constant amount of extra space.

Optimal Approach: Sliding Window

A more efficient approach is to use a sliding window. We maintain a window and keep track of the product of the elements within the window. We expand the window to the right by including more elements, and if the product becomes greater than or equal to k, we shrink the window from the left until the product is less than k again. The number of subarrays ending at the current index is then the length of the current window.

Code (Python):

def numSubarrayProductLessThanK(nums, k):
    if k <= 1:
        return 0
    
    count = 0
    product = 1
    left = 0
    
    for right in range(len(nums)):
        product *= nums[right]
        while product >= k:
            product /= nums[left]
            left += 1
        count += right - left + 1
    
    return count

Time Complexity: O(n), where n is the length of the input array. Although there is a nested while loop, each element is visited at most twice (once by the right pointer and once by the left pointer).

Space Complexity: O(1), as we are only using a constant amount of extra space.

Edge Cases:

  • If k is less than or equal to 0 or 1, there will be no subarrays with a product less than k, so we return 0.
  • If the input array is empty, there will be no subarrays, so we return 0.
  • The numbers in the input array must be greater than zero.

Explanation

The sliding window technique efficiently counts the number of subarrays whose product is less than k. We maintain a window defined by the left and right pointers, and keep track of the product of the elements within this window. As we move the right pointer to expand the window, we check if the product exceeds k. If it does, we move the left pointer to shrink the window until the product is once again less than k. The number of subarrays ending at the current right index is simply the length of the current window (right - left + 1). We accumulate these counts to get the total number of subarrays that satisfy the condition.