🧠
Sliding Window (Two Pointers)
💡 This approach uses a variable-size sliding window to efficiently count subarrays by maintaining a product and adjusting window boundaries, avoiding repeated product calculations.
Intuition
Expand the right pointer to include elements while product < k, and shrink from the left when product ≥ k, counting valid subarrays ending at each right pointer.
Algorithm
- Initialize product = 1, left = 0, count = 0.
- Iterate right pointer over array:
- Multiply product by nums[right].
- While product ≥ k and left ≤= right, divide product by nums[left] and increment left.
- Add (right - left + 1) to count (all subarrays ending at right with product < k).
💡 The key insight is that all subarrays ending at right and starting between left and right are valid if product < k.
def numSubarrayProductLessThanK(nums, k):
if k <= 1:
return 0
product = 1
count = 0
left = 0
for right in range(len(nums)):
product *= nums[right]
while product >= k and left <= right:
product /= nums[left]
left += 1
count += right - left + 1
return count
# Driver code
if __name__ == '__main__':
print(numSubarrayProductLessThanK([10,5,2,6], 100)) # Expected output: 8
Line Notes
if k <= 1:No valid subarray if k ≤ 1
product = 1Initialize product for sliding window
left = 0Left pointer starts at 0
for right in range(len(nums))Right pointer moves forward
product *= nums[right]Include new element in product
while product >= k and left <= right:Shrink window from left if product too large
product /= nums[left]Remove left element from product
left += 1Move left pointer right
count += right - left + 1Count all valid subarrays ending at right
public class Solution {
public int numSubarrayProductLessThanK(int[] nums, int k) {
if (k <= 1) return 0;
int product = 1, count = 0, left = 0;
for (int right = 0; right < nums.length; right++) {
product *= nums[right];
while (product >= k && left <= right) {
product /= nums[left++];
}
count += right - left + 1;
}
return count;
}
public static void main(String[] args) {
Solution sol = new Solution();
System.out.println(sol.numSubarrayProductLessThanK(new int[]{10,5,2,6}, 100)); // 8
}
}
Line Notes
if (k <= 1) return 0;No valid subarray if k ≤ 1
int product = 1, count = 0, left = 0;Initialize variables for sliding window
for (int right = 0; right < nums.length; right++) {Right pointer moves forward
product *= nums[right];Include new element in product
while (product >= k && left <= right) {Shrink window from left if product too large
product /= nums[left++];Remove left element and move left pointer
count += right - left + 1;Count valid subarrays ending at right
#include <iostream>
#include <vector>
using namespace std;
int numSubarrayProductLessThanK(vector<int>& nums, int k) {
if (k <= 1) return 0;
int product = 1, count = 0, left = 0;
for (int right = 0; right < nums.size(); ++right) {
product *= nums[right];
while (product >= k && left <= right) {
product /= nums[left++];
}
count += right - left + 1;
}
return count;
}
int main() {
vector<int> nums = {10,5,2,6};
cout << numSubarrayProductLessThanK(nums, 100) << endl; // 8
return 0;
}
Line Notes
if (k <= 1) return 0;No valid subarray if k ≤ 1
int product = 1, count = 0, left = 0;Initialize sliding window variables
for (int right = 0; right < nums.size(); ++right) {Right pointer moves forward
product *= nums[right];Include new element in product
while (product >= k && left <= right) {Shrink window from left if product too large
product /= nums[left++];Remove left element and move left pointer
count += right - left + 1;Count valid subarrays ending at right
function numSubarrayProductLessThanK(nums, k) {
if (k <= 1) return 0;
let product = 1, count = 0, left = 0;
for (let right = 0; right < nums.length; right++) {
product *= nums[right];
while (product >= k && left <= right) {
product /= nums[left++];
}
count += right - left + 1;
}
return count;
}
// Test
console.log(numSubarrayProductLessThanK([10,5,2,6], 100)); // 8
Line Notes
if (k <= 1) return 0;No valid subarray if k ≤ 1
let product = 1, count = 0, left = 0;Initialize variables for sliding window
for (let right = 0; right < nums.length; right++) {Right pointer moves forward
product *= nums[right];Include new element in product
while (product >= k && left <= right) {Shrink window from left if product too large
product /= nums[left++];Remove left element and move left pointer
count += right - left + 1;Count valid subarrays ending at right
Each element is visited at most twice (once when right pointer moves forward, once when left pointer moves forward), so linear time.
💡 For n=100000, this means about 200000 operations, which is efficient for large inputs.
Interview Verdict: Accepted and optimal
This approach is efficient and suitable for interview coding, demonstrating mastery of sliding window technique.