Check if Number is Prime in DSA Rust - Time & Space Complexity
We want to understand how the time needed to check if a number is prime grows as the number gets bigger.
How does the number size affect the steps we take to decide if it is prime?
Analyze the time complexity of the following code snippet.
fn is_prime(n: u32) -> bool {
if n <= 1 {
return false;
}
for i in 2..=((n as f64).sqrt() as u32) {
if n % i == 0 {
return false;
}
}
true
}
This code checks if a number is prime by testing divisibility from 2 up to the square root of the number.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Loop checking divisibility from 2 to √n.
- How many times: Approximately √n times in the worst case.
As the number n grows, the number of checks grows roughly with the square root of n.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 3 checks (2,3) |
| 100 | About 10 checks (2 to 10) |
| 1000 | About 31 checks (2 to 31) |
Pattern observation: The number of steps grows slower than n, closer to the square root of n.
Time Complexity: O(√n)
This means the time to check if a number is prime grows roughly with the square root of the number size.
[X] Wrong: "We must check all numbers from 2 up to n-1 to find if n is prime."
[OK] Correct: Checking up to n-1 is unnecessary because if n has a divisor larger than its square root, it must also have a smaller one. So checking up to √n is enough and faster.
Understanding this time complexity helps you explain efficient prime checking, a common building block in many problems. It shows you can find smarter ways to reduce work, a key skill in coding interviews.
"What if we checked divisibility only by prime numbers up to √n? How would the time complexity change?"
Practice
prime?Solution
Step 1: Understand the definition of prime number
A prime number is a number greater than 1 that has no divisors other than 1 and itself.Step 2: Compare options with definition
Only It has exactly two distinct positive divisors: 1 and itself. correctly states this definition.Final Answer:
It has exactly two distinct positive divisors: 1 and itself. -> Option DQuick Check:
Prime = two divisors [OK]
- Thinking even numbers are always prime
- Confusing prime with odd numbers
- Assuming 1 is prime
n is prime?Solution
Step 1: Analyze the loop range for divisor checking
We check divisors from 2 up to n-1 (exclusive of n) to find if any divides n.Step 2: Check each option's loop and condition
for i in 2..n { if n % i == 0 { return false; } } true correctly loops from 2 to n-1 and returns false if divisor found; others have errors like including n or wrong condition.Final Answer:
for i in 2..n { if n % i == 0 { return false; } } true -> Option BQuick Check:
Loop 2 to n-1 and check divisibility [OK]
- Including n in the loop range
- Starting loop from 1 instead of 2
- Using wrong condition for divisibility
is_prime(11)?fn is_prime(n: u32) -> bool {
if n <= 1 { return false; }
for i in 2..n {
if n % i == 0 {
return false;
}
}
true
}Solution
Step 1: Check input and loop behavior for n=11
11 is greater than 1, so the function proceeds to loop from 2 to 10 checking divisibility.Step 2: Test divisibility of 11 by numbers 2 to 10
11 is not divisible by any number between 2 and 10, so loop completes without returning false.Final Answer:
true -> Option AQuick Check:
11 is prime, so function returns true [OK]
- Assuming 11 is not prime
- Confusing loop range
- Expecting runtime errors incorrectly
fn is_prime(n: u32) -> bool {
if n < 2 { return false; }
for i in 2..=n {
if n % i == 0 {
return false;
}
}
true
}Solution
Step 1: Analyze the loop range 2..=n
The loop includes n itself, so n % n == 0 is always true, causing immediate false return.Step 2: Understand correct loop range
Loop should be 2..n (exclusive of n) to avoid checking n against itself.Final Answer:
Loop includes n, causing always false for n > 1 -> Option CQuick Check:
Loop must exclude n to avoid false negatives [OK]
- Including n in divisor checks
- Wrong loop start index
- Misunderstanding return conditions
n. Which Rust code snippet correctly implements this?Solution
Step 1: Understand optimization using square root
Checking divisors up to sqrt(n) is enough because larger factors pair with smaller ones.Step 2: Analyze each option's loop range and correctness
for i in 2..=((n as f64).sqrt() as u32) { if n % i == 0 { return false; } } true correctly casts n to float, computes sqrt, casts back to u32, and loops up to that value.Final Answer:
for i in 2..=((n as f64).sqrt() as u32) { if n % i == 0 { return false; } } true -> Option AQuick Check:
Loop up to sqrt(n) for efficient prime check [OK]
- Checking divisors beyond sqrt(n)
- Starting loop from 1 instead of 2
- Incorrect casting causing errors
Ready to prove it?
Pass the test and this pattern moves unknown
