Bird
Raised Fist0
DSA Rustprogramming~5 mins

Sieve of Eratosthenes Find All Primes in DSA Rust - Time & Space Complexity

Choose your learning style10 modes available
Time Complexity: Sieve of Eratosthenes Find All Primes
O(n log log n)
Understanding Time Complexity

We want to understand how the time needed to find all prime numbers grows as we check bigger ranges.

Specifically, how does the Sieve of Eratosthenes perform when finding primes up to a number n?

Scenario Under Consideration

Analyze the time complexity of the following code snippet.


fn sieve(n: usize) -> Vec<bool> {
    let mut primes = vec![true; n + 1];
    primes[0] = false;
    primes[1] = false;
    let mut p = 2;
    while p * p <= n {
        if primes[p] {
            let mut i = p * p;
            while i <= n {
                primes[i] = false;
                i += p;
            }
        }
        p += 1;
    }
    primes
}
    

This code marks multiples of each prime number as not prime, effectively finding all primes up to n.

Identify Repeating Operations

Identify the loops, recursion, array traversals that repeat.

  • Primary operation: Marking multiples of primes as not prime inside nested loops.
  • How many times: Outer loop runs roughly up to √n, inner loop runs for multiples of each prime.
How Execution Grows With Input

As n grows, the number of operations grows a bit faster than n but much slower than n squared.

Input Size (n)Approx. Operations
10~20
100~300
1000~5000

Pattern observation: The work grows roughly proportional to n times the logarithm of logarithm of n, which is slower than n log n but faster than linear.

Final Time Complexity

Time Complexity: O(n log log n)

This means the time grows a little faster than n but much slower than n squared, making it efficient for large n.

Common Mistake

[X] Wrong: "The algorithm checks every number against every other number, so it must be O(n²)."

[OK] Correct: The sieve only marks multiples of primes, skipping many numbers early, so it does far fewer operations than n squared.

Interview Connect

Understanding this time complexity shows you can analyze nested loops with decreasing work and recognize efficient prime-finding methods.

Self-Check

"What if we started marking multiples from 2*p instead of p*p? How would the time complexity change?"

Practice

(1/5)
1. What is the main purpose of the Sieve of Eratosthenes algorithm?
easy
A. To sort a list of numbers in ascending order
B. To find the greatest common divisor of two numbers
C. To find all prime numbers up to a given limit
D. To calculate the factorial of a number

Solution

  1. Step 1: Understand the algorithm's goal

    The Sieve of Eratosthenes is designed to identify prime numbers efficiently.
  2. Step 2: Recognize the output of the algorithm

    It marks multiples of primes as non-prime, leaving primes unmarked up to a limit.
  3. Final Answer:

    To find all prime numbers up to a given limit -> Option C
  4. Quick Check:

    Sieve of Eratosthenes = Find primes [OK]
Hint: Sieve marks multiples to find primes fast [OK]
Common Mistakes:
  • Confusing it with sorting algorithms
  • Thinking it calculates factorials
  • Assuming it finds divisors instead of primes
2. Which Rust code snippet correctly initializes a boolean vector is_prime of size n+1 with all values set to true except for indices 0 and 1?
easy
A. let is_prime = vec![false; n+1]; is_prime[0] = true; is_prime[1] = true;
B. let mut is_prime = vec![true; n+1]; is_prime[0] = false; is_prime[1] = false;
C. let mut is_prime = vec![true; n]; is_prime[0] = false; is_prime[1] = false;
D. let mut is_prime = vec![false; n]; is_prime[0] = true; is_prime[1] = true;

Solution

  1. Step 1: Initialize vector with true values

    We want a mutable vector of size n+1 with all true values initially.
  2. Step 2: Set indices 0 and 1 to false

    Since 0 and 1 are not prime, we set those positions to false.
  3. Final Answer:

    let mut is_prime = vec![true; n+1]; is_prime[0] = false; is_prime[1] = false; -> Option B
  4. Quick Check:

    Initialize true vector and mark 0,1 false [OK]
Hint: Use vec![true; n+1] and set 0,1 false [OK]
Common Mistakes:
  • Using size n instead of n+1
  • Not making vector mutable
  • Setting wrong indices to true/false
3. What will be the output of the following Rust code snippet that uses the Sieve of Eratosthenes to find primes up to 10?
let n = 10;
let mut is_prime = vec![true; n+1];
is_prime[0] = false;
is_prime[1] = false;
for i in 2..=((n as f64).sqrt() as usize) {
    if is_prime[i] {
        let mut j = i * i;
        while j <= n {
            is_prime[j] = false;
            j += i;
        }
    }
}
let primes: Vec<usize> = is_prime.iter().enumerate()
    .filter(|&(_, &prime)| prime)
    .map(|(index, _)| index)
    .collect();
println!("{:?}", primes);
medium
A. [2, 3, 5, 7]
B. [1, 2, 3, 5, 7]
C. [2, 3, 4, 5, 7]
D. [0, 2, 3, 5, 7]

Solution

  1. Step 1: Initialize and mark non-primes

    Indices 0 and 1 are false. Loop marks multiples of 2 and 3 as false.
  2. Step 2: Collect indices marked true

    Only 2, 3, 5, and 7 remain true and are collected as primes.
  3. Final Answer:

    [2, 3, 5, 7] -> Option A
  4. Quick Check:

    Primes up to 10 = [2, 3, 5, 7] [OK]
Hint: Primes under 10 are 2,3,5,7 only [OK]
Common Mistakes:
  • Including 1 or 0 as prime
  • Including 4 which is not prime
  • Not starting j from i*i
4. Identify the bug in this Rust code snippet implementing the Sieve of Eratosthenes for n = 15:
let n = 15;
let mut is_prime = vec![true; n+1];
is_prime[0] = false;
is_prime[1] = false;
for i in 2..n {
    if is_prime[i] {
        let mut j = i * 2;
        while j <= n {
            is_prime[j] = false;
            j += i;
        }
    }
}
medium
A. Indices 0 and 1 should be set to true
B. The vector size should be n, not n+1
C. The outer loop should run from 2 to sqrt(n), not 2 to n
D. The inner loop should start from i * i, not i * 2

Solution

  1. Step 1: Check inner loop start index

    Starting from i*2 marks some numbers multiple times, less efficient.
  2. Step 2: Correct start is i*i for marking multiples

    Because smaller multiples are already marked by smaller primes.
  3. Final Answer:

    The inner loop should start from i * i, not i * 2 -> Option D
  4. Quick Check:

    Start marking multiples from i*i for efficiency [OK]
Hint: Start marking multiples from i squared [OK]
Common Mistakes:
  • Starting inner loop from i*2 wastes time
  • Looping outer from 2 to n instead of sqrt(n)
  • Wrong vector size causing index errors
5. You want to find all prime numbers up to 50 using the Sieve of Eratosthenes in Rust. After running the sieve, you want to return a vector of primes but exclude the prime number 2 from the result. Which modification to the code below achieves this?
let n = 50;
let mut is_prime = vec![true; n+1];
is_prime[0] = false;
is_prime[1] = false;
for i in 2..=((n as f64).sqrt() as usize) {
    if is_prime[i] {
        let mut j = i * i;
        while j <= n {
            is_prime[j] = false;
            j += i;
        }
    }
}
let primes: Vec<usize> = is_prime.iter().enumerate()
    .filter(|&(_, &prime)| prime)
    .map(|(index, _)| index)
    .collect();
hard
A. Add a filter after collecting primes: primes.into_iter().filter(|&x| x != 2).collect()
B. Set is_prime[2] = false before the outer loop
C. Start outer loop from 3 instead of 2
D. Remove is_prime[0] = false line

Solution

  1. Step 1: Understand the sieve marks primes correctly

    All primes including 2 are marked true in is_prime.
  2. Step 2: Exclude 2 after collecting primes

    Filtering out 2 after collecting primes avoids affecting sieve logic.
  3. Final Answer:

    Add a filter after collecting primes: primes.into_iter().filter(|&x| x != 2).collect() -> Option A
  4. Quick Check:

    Filter out 2 after sieve to exclude it [OK]
Hint: Filter out 2 after collecting primes [OK]
Common Mistakes:
  • Setting is_prime[2] = false breaks sieve correctness
  • Starting loop from 3 misses marking multiples of 2
  • Removing is_prime[0] = false causes wrong prime marking
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard