Home > Enterprise >  Sliding window algorithm to calculate the list of all k-element contiguous subarray products of an a
Sliding window algorithm to calculate the list of all k-element contiguous subarray products of an a

Time:10-27

I have an array of n positive integers. I want to calculate a list of all contiguous subarray products of size k modulo p. For instance for the following array:

a = [3, 12, 5, 2, 3, 7, 4, 3]

with k = 3 and p = 12, the ordered list of all k-sized contiguous subarray products will be:

k_products = [180, 120, 30, 42, 84, 84]

and modulo p we have:

k_products_p = [0, 0, 6, 6, 0, 0]

we can easily compute k_products using a sliding window. All we have to do is to compute the product for the first k-sized subarray and then compute the next elements of k_product using the following formula:

k_product[i] = k_product[i - 1] * a[i k] / a[i - 1]

and after forming the whole list, we can compute k_product[i] % p for each i to get k_product_p. That's it. O(n) complexity is pretty good.

But if the elements of a[i] are big, the elements of k_product may overflow, and thus we cannot compute k_product_p. Plus, we cannot, for example do the following:

k_product[i] = ((k_product[i - 1] % p) * (a[i k] % p) / (a[i - 1] % p)) % p // incorrect

So is there a fast algorithm to do this? Note that p is not necessarily prime and it is also not necessarily coprime to the elements of a.

Edit: As mentioned in the comments, there will be no overflow in python, but working with very big numbers will be time-consuming.

CodePudding user response:

This is not a sliding window algorithm, but it is a simple and effective way to solve this problem in O(n) time without any division:

Let A be your original array. We will imagine that there is a "mark" on every kth element of A -- elements A[0], A[k], A[2k], etc. This ensures that every k-length window in A will contain exactly one mark.

Now, make two new arrays B and C, such that:

  • In array B, each element B[i] will contain the product (mod p) of A[i] and all following elements up to but not including the next mark. If A[i] is marked, then B[i] = 1. You can calculate this in a single pass backward from i=n-1 to i=0.

  • In array C, each element C[i] will contain the product (mod p) of A[i] and all preceding elements down to and including the previous mark. If A[i] is marked, then C[i] = A[i]. You can calculate this in a single pass forward from i=0 to i=n-1.

Now, you can easily calculate the complete product of any k-length window in constant time, because the product of any window from A[i]...A[i k-1] is just B[i] * C[i k-1]. Remember that there is exactly one mark inside the window. B[i] is the product of the elements before the mark, and C[i k-1] is the product of the marked element and the elements after it.

  • Related