Given an array of positive numbers and a number k, find the number of subarrays having product exactly equal to k. We may assume that there is no overflow.
Input : arr = [2, 1, 1, 1, 4, 5] k = 4 Output : 4 1st subarray : arr[1..4] 2nd subarray : arr[2..4] 3rd subarray : arr[3..4] 4th subarray : arr Input : arr = [1, 2, 3, 4, 1] k = 24 Output : 4 1st subarray : arr[0..4] 2nd subarray : arr[1..4] 3rd subarray : arr[1..3] 4th subarray : arr[0..3]
A simple solution is to consider all subarrays and find their products. For every product, check if it is equal to k. If yes, then increment result.
An efficient solution is to use sliding window technique can be used to solve the problem. We use two pointers start and end to represent starting and ending point of sliding window.
Initially both start and end point to the beginning of the array, i.e. index 0. Keep incrementing end until product p < k. As soon as p becomes equal to k stop incrementing end and check whether the current position of end is followed by a series of 1s in the array. If yes then those 1s will also contribute to the subarray count. Store the count of these succeeding 1s in a variable countOnes. After this keep incrementing start until p equals to k while adding (countOnes + 1) to result. If start coincides with end then again start from incrementing end and follow the same procedure. Do this until end < array size.
Why countOnes + 1 is added to result?
Consider the second test case in the above sample cases. If we follow the above mentioned procedure, then after incrementing end, we will reach at start = 0 and end = 3. After this the countOnes is set equal to 1. How many subarrays are there for start = 0 ? There are two subarrays : arr[0..3] and arr[0..4]. Observe that subarray[0..3] is what we have found using sliding window technique. This increases the result count by 1 and is what represented by + 1 in expression countOnes + 1. The other subarray[0..4] is simply obtained by appending single 1 to the subarray[0..3], i.e. adding countOnes number of 1s one at a time. Let us try to generalise it. Suppose arr[0..i] is the subarray obtained using sliding window technique and let countOnes = j. Then we can expand this subarray by unit length at a time by appending single 1 to this subarray. After appending a single 1 to arr[0..i] the new subarray is arr[0..i+1] and result is also increased by 1. countOnes now decrease by 1 and equals j – 1. We can continuously append single 1 at a time and obtain a new subarray until countOnes is not equal to zero.
Thus the result count increases by countOnes and is represented as countOnes in expression countOnes + 1. So for every increment in start until p equals k simply add countOnes + 1 to the result.
The algorithm can be listed as:
1. Initialize start = end = 0 2. Initialize res = 0, p = 1 3. Increment end until p < k 4. When p = k do: Set countOnes = number of succeeding ones res += (countOnes+1) Increment start until p = k and do res += (countOnes+1) 5. Stop if end = n
Time Complexity: O(n)
Auxiliary Space : O(n)