Given an integer n
, return the number of prime numbers that are strictly less than n
.
Example 1:
Input: n = 10 Output: 4 Explanation: There are 4 prime numbers less than 10, they are 2, 3, 5, 7.
Example 2:
Input: n = 0 Output: 0
Example 3:
Input: n = 1 Output: 0
Constraints:
0 <= n <= 5 * 106
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
To count primes using a brute force method, we essentially check every number one by one to see if it is a prime number. We do this by testing if any smaller number can perfectly divide it. If no smaller number divides it, we know that number is prime and increment our count.
Here's how the algorithm would work step-by-step:
def count_primes_brute_force(target_number):
number_of_primes = 0
for number in range(2, target_number):
is_prime = True
# Iterate from 2 up to the number to check divisibility
for potential_divisor in range(2, number):
# Check if the number is divisible by the potential divisor
if number % potential_divisor == 0:
is_prime = False
break
# If, after checking all potential divisors, is_prime is still True,
# then the number is prime, increment the counter.
if is_prime:
number_of_primes += 1
return number_of_primes
Finding prime numbers one by one can take a long time. Instead, we'll use a clever approach to quickly identify all non-prime numbers, leaving us with the primes. This is like finding the bad apples in a basket to easily see which ones are good.
Here's how the algorithm would work step-by-step:
def count_primes(number):
if number <= 2:
return 0
is_prime = [True] * number
is_prime[0] = is_prime[1] = False
# Iterate up to the square root for optimization.
for i in range(2, int(number**0.5) + 1):
if is_prime[i]:
# Start marking from i*i since smaller multiples are already marked.
for multiple in range(i*i, number, i):
is_prime[multiple] = False
# Count the remaining primes.
prime_count = sum(is_prime)
return prime_count
Case | How to Handle |
---|---|
Input n is 0 | Return 0 immediately, as there are no primes less than 0. |
Input n is 1 | Return 0 immediately, as there are no primes less than 1. |
Input n is 2 | Return 0 immediately, as 2 is not less than 2. |
Input n is a large number close to the maximum integer value | Ensure the Sieve of Eratosthenes algorithm implementation does not cause integer overflow when calculating indices or allocating memory for the boolean array. |
Negative input for n | Treat negative inputs as 0 and return 0, as the problem specifies non-negative numbers. |
Input n is a prime number, such as 7 | The algorithm should correctly count primes strictly less than n, excluding n itself. |
The input n is a perfect square, such as 9 | The algorithm should not double count primes when checking divisibility, this is inherent in the Sieve of Eratosthenes. |
Input n results in a very large boolean array (memory constraints) | Consider memory usage optimization if n is excessively large; an alternative approach might be needed if memory becomes a bottleneck. |