Post

Sieve of Eratosthenes

Given a number ‘n’, we need to print all the prime numbers up to ‘n’.

1
2
3
4
for(int i = 2; i * i <= n; i++)
{
    if(prime(i)) v.push_back(i);
}

This is the normal way to find primes up to ‘n’, but the time complexity of the above code is O(n * sqrt(n)), which takes a lot of time.
Therefore, we will use the Sieve of Eratosthenes algorithm for better time complexity.

How It Works

The algorithm works on a simple principle: any multiple of a prime number cannot be prime.
By systematically marking off these multiples, we are left with only prime numbers.

First, create a list of consecutive integers from 2 to ‘n’ (since 0 and 1 are not prime), then initialize them with 1 (assuming all numbers are prime initially).
For n = 30, the process looks like this:

11111111111111111111111111111
23456789101112131415161718192021222324252627282930

In this list, the first number is 2, which is the first prime number. Since any multiple of a prime can never be prime, we will mark off all the multiples of 2 up to 30.

11010101010101010101010101010
23 5 7 9 11 13 15 17 19 21 23 25 27 29 

Now the second number (and also the second prime) is 3. We will mark off all the multiples of 3 up to 30 in the same way.

11010100010100010100010100010
23 5 7   11 13   17 19   23 25   29 

After 3, the next number is 4, but it’s not a prime number because it’s a multiple of 2. The multiples of 4 are also divisible by 2, so they were previously marked off by 2.
The next number is 5, and it’s a prime number. Therefore, we mark off all the multiples of 5.

11010100010100010100010000010
23 5 7   11 13   17     23     29 

The next number is 6, which is a multiple of both 2 and 3, so it’s not a prime number. The multiples of 6 were already marked off by 2 or 3.
This marking off cycle repeats until all the multiples of each prime are marked off and only the primes up to ‘n’ remain in the list.
For n = 30, the final list looks like this:

11010100010100010100010000010
23 5 7   11 13   17     23     29 

The prime numbers are 2, 3, 5, 7, 11, 13, 17, 19, 23, and 29.

Here is the code implementation of the Sieve of Eratosthenes algorithm:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <bits/stdc++.h>
using namespace std;

// function to find all prime numbers up to 'n'
vector<int> findAllPrimes(int n) {
    // initialize with 1 (assuming all numbers are prime initially)
    vector<int> prime(n + 1, 1);
    
    // 0 and 1 are not prime
    prime[0] = prime[1] = 0; 
    
    // apply Sieve of Eratosthenes
    for (int i = 2; i <= sqrt(n); ++i) {
        if (prime[i] == 1) {
            for (int j = i * i; j <= n; j += i) {
                // mark multiples of prime numbers as not prime
                prime[j] = 0; 
            }
        }
    }
    
    vector<int> ans;
    // collect prime numbers
    for (int i = 2; i <= n; ++i) 
    {
        if (prime[i] == 1) ans.push_back(i);
    }
    return ans;
}

int main() 
{
    int n = 30;
    vector<int> primes = findAllPrimes(n);

    cout << "Prime numbers less than or equal to " << n << ":" << endl;
    for (auto prime : primes) {
        cout << prime << " ";
    }
    cout << endl;

    return 0;
}
Time and Space Complexity for the Sieve of Eratosthenes algorithm:

Time Complexity = O(nlog(logn))
Space Complexity = O(n)

Here is an animated visualization of how the Sieve of Eratosthenes works, for n = 120: Animation_Sieve_of_Eratosthenes

This post is licensed under CC BY 4.0 by the author.