Suppose we're given an array of positive numbers M, say [3, 5, 7] and we want to enumerate all numbers which are multiple of any one of them, less than some upper bound, say K, so in this case 0, 3, 5, 6, 7, 9, 10, 12, 14, 15....
How would one do it efficiently when size of M is large?
One Naive approach is to start from 0 and for each value check if it divides any value in M, which is not great as values may be large so most numbers won't be enumerated but will waste computation.
I would like to enumerate in such a way that time complexity is as close to theoretical minimum as possible, ie. O(Number of elements in sequence), which means values which are common multiples, for example 6 in sequence of [2, 3] ideally shouldn't require more computation than any other value.
I think you can optimize the algorithm by using heap data structure (
PriorityQueuequeuein below Python code) to keep track of the next smallest multiple of the numbers inMlist that will be added to the enumerated list until it reachesK. The advantage heap data structure is that it hasO(1)lookup time for finding the smallest value in the list andO(log(n))for insertion and deletion.Initially the queue will have the
Mitems, each has the following tuple structure(<num 1>, <num 1>), where the first item is the next multipled value to append to the list and the second item is the original value.While the last enumerated number is less than
Kand the queue is empty, we can continuously pull the lexicographically smallest item from the queue and append to the enumerated list if the value not exist in the list and value is less than or equal toK. Afterwards, we append a new structure into the queue as(<num> + <multiple>, <multiple>)to represent the next multiple of the original value (<multiple>)The estimated time complexity would be
O(Klog(M))which is more efficient thanO(KM)in the original post