Remove all multiples of a given set of numbers from a given range

I am stuck in a problem where it says, given a number Nand a set of numbers,, S = {s1,s2,.....sn}where s1 < s2 < sn < N, remove all multiples {s1, s2,....sn}from the range1..N

Example:

Let N = 10
S = {2,4,5}
Output: {1, 7, 9}
Explanation: multiples of 2 within range: 2, 4, 6, 8
             multiples of 4 within range: 4, 8
             multiples of 5 within range: 5, 10 

I would like to have an algorithmic approach, psuedocode, and not a complete solution.

What I tried:

(Considering the same example as above) 

 1. For the given N, find all the prime factors of that number.
    Therefore, for 10, prime-factors are: 2,3,5,7
    In the given set, S = {2,4,5}, the prime-factors missing from 
    {2,3,5,7} are {3,7}.  
 2. First, check prime-factors that are present: {2,5}
    Hence, all the multiples of them will be removed 
    {2,4,5,6,8,10}
 3. Check for non-prime numbers in S = {4}
 4. Check, if any divisor of these numbers has already been 
    previously processed.
         > In this case, 2 is already processed.
         > Hence no need to process 4, as all the multiples of 4 
           would have been implicitly checked by the previous 
           divisor.
    If not,
         > Remove all the multiples from this range.
 5. Repeat for all the remaining non primes in the set.

Please suggest your thoughts!

+4
source share
3 answers

This can be solved in O (N log (n)) time and O (N) additional memory using something similar to a sieve of Eratosthenes.

isMultiple[1..N] = false

for each s in S:
    t = s
    while t <= N:
        isMultiple[t] = true
        t += s

for i in 1..N:
    if not isMultiple[i]:
        print i

To store the array isMultiple, O (N) memory is used.


The complexity of time is O (N log (n)). Indeed, the inner while loop will execute N / s 1 for the first element in S, then N / s 2 for the second, etc.

N/s 1 + N/s 2 +... + N/s n.

N/s 1 + N/s 2 +... + N/s n  = N * (1/s 1 + 1/s 2 +... + 1/s n) <= N * ( 1/1 + 1/2 +... + 1/n).

, s 1 < s 2 <... < s n, - {1, 2,.. n}.

1/1 + 1/2 +... + 1/n O (log (n)) (, . this), , O (N log (n)).

+4

:

let set X be our output set.

for each number, n, between 1 and N:
    for each number, s, in set S:
        if s divides n:
            stop searching S, and move onto the next number,n.
        else if s is the last element in S:
            add n to the set X.

, , S , , -

+1

Since S is sorted, we can guarantee complexity O(N)by skipping elements in S already marked ( http://codepad.org/Joflhb7x ):

N = 10
S = [2,4,5]
marked = set()
i = 0
curr = 1

while curr <= N:
  while curr < S[i]:
    print curr
    curr = curr + 1

  if not S[i] in marked:
    mult = S[i]

    while mult <= N:
      marked.add(mult)
      mult = mult + S[i]

  i = i + 1
  curr = curr + 1

  if i == len(S):
    while curr <= N:
      if curr not in marked:
        print curr
      curr = curr + 1

print list(marked)
+1
source

Source: https://habr.com/ru/post/1691263/


All Articles