Count Primes

Updated on 09 May, 2025
Count Primes header image

Problem Statement

This problem requires determining the count of prime numbers that exist below a given integer n. A prime number is a natural number greater than 1 that has no positive divisors other than 1 and itself. For a given integer n, the task is to compute how many prime numbers are there which are strictly less than n. This involves an efficient way to verify primality for numbers and count them up to n.

Examples

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

Approach and Intuition

In order to determine how many prime numbers are less than a given integer n, we follow a systematic approach:

  1. Understanding Primes: Recognize that prime numbers are those greater than 1 that are divisible only by 1 and themselves.

  2. Use of Sieve of Eratosthenes: This is an efficient classical algorithm to generate all primes smaller than a given number n. It works by iteratively marking the multiples of each prime starting from 2.

  3. Algorithm Steps:

    • Create a list of boolean values initialized to True, corresponding to each number up to n-1.
    • The value at position i represents whether the number i is a prime or not.
    • Starting from the first prime number 2, mark all of its multiples as non-prime.
    • Move to the next number and repeat if it is marked as True (prime). Continue this process up to sqrt(n), because a non-prime number will have at least one divisor less than or equal to sqrt(n).
    • Finally, count all the True values in the list except for positions 0 and 1 (which represent 0 and 1, non-primes).
  4. Handling Special Cases: If n is 0 or 1, return 0 immediately as there are no numbers less than 2 that are prime.

This approach leverages the Sieve of Eratosthenes, optimizing primality testing for multiple numbers and is effective for large values of n, up to the constraint maximum of 5 * 10^6. By pre-computing the primes, previously marked non-prime numbers are skipped, reducing unnecessary calculations and ensuring that the operation completes in reasonable time for high values of n.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    int countPrimes(int n) {
        if (n <= 2) {
            return 0;
        }

        vector<bool> prime(n, true); // Mark all numbers as prime initially
        for (int i = 2; i * i < n; i++) {
            if (prime[i]) {
                for (int j = i * i; j < n; j += i) {
                    prime[j] = false; // Mark as non-prime
                }
            }
        }

        int primeCount = 0;
        for (int k = 2; k < n; k++) {
            if (prime[k]) {
                primeCount++; // Count primes
            }
        }

        return primeCount;
    }
};

Implement the "Count Primes" solution in C++ by using an optimized algorithm to determine the number of prime numbers less than a non-negative number ( n ). This algorithm leverages the Sieve of Eratosthenes method, which iteratively marks the multiples of each prime starting from 2 as non-prime.

Follow these steps to execute the solution effectively:

  1. Start by handling the edge case: if ( n ) is less than or equal to 2, immediately return 0 as there are no prime numbers.

  2. Initialize a boolean vector, prime, with all elements set to true. This vector represents the primality of numbers from 0 to ( n-1 ).

  3. Use a loop to traverse numbers starting from 2 up to the square root of ( n ). This is because any factor greater than the square root would have a corresponding factor less than the square root, effectively covering all numbers in the range without excess computation.

  4. Inside the loop, if a number is marked as prime, iterate through its multiples starting from its square and mark them as non-prime in the vector. This is achieved using another loop which increments by the number itself, ensuring all multiples are marked.

  5. After marking non-prime numbers, iterate through the vector to count the numbers that remain prime.

  6. Return the count of prime numbers found.

This method is efficient due to its avoidance of redundant checks and minimal memory usage proportional to ( n ), ensuring a balance between time complexity and space usage. This approach significantly reduces the computational complexity compared to naive methods, especially for large values of ( n ). By meticulously marking non-primes through subsequent multiplications, major computations are limited to the necessary minimum.

java
class Solution {
    public int primeCounter(int limit) {
        if (limit <= 2) {
            return 0;
        }

        boolean[] isComposite = new boolean[limit];
        for (int current = 2; current <= (int) Math.sqrt(limit); ++current) {
            if (!isComposite[current]) {
                for (int multiple = current * current; multiple < limit; multiple += current) {
                    isComposite[multiple] = true;
                }
            }
        }

        int count = 0;
        for (int index = 2; index < limit; index++) {
            if (!isComposite[index]) {
                count++;
            }
        }

        return count;
    }
}

The provided Java program efficiently counts the number of prime numbers less than a given number limit. It uses the Sieve of Eratosthenes algorithm, which is an efficient way to identify prime numbers. Here's how the program operates:

  1. First, check if the input limit is less than or equal to 2. If true, return 0 because there are no prime numbers less than 2.
  2. Initialize a boolean array isComposite to keep track of composite (non-prime) numbers. The size of this array is limit, and by default, all entries are set to false, indicating all numbers are initially assumed to be prime.
  3. Iterate through numbers starting from 2 up to the square root of limit. For each number current that has not been marked as composite:
    • Mark all multiples of current, starting from current*current to less than limit, as composite. The increment for marking composites is current, to skip directly to the next multiple.
  4. After marking the composites, count all numbers from 2 up to limit that are not marked as composite. Each unmarked number is a prime.
  5. Return the total count of prime numbers.

By utilizing the Sieve of Eratosthenes, the algorithm efficiently avoids unnecessary computations, particularly with larger values of limit, by reducing the number of multiples it checks and marking, thereby optimizing the overall counting process.

python
class Solution:
    def prime_count(self, limit: int) -> int:
        if limit <= 2:
            return 0

        is_prime = [False, False] + [True] * (limit - 2)
        for current in range(2, int(sqrt(limit)) + 1):
            if is_prime[current]:
                for multiple in range(current * current, limit, current):
                    is_prime[multiple] = False

        return sum(is_prime)

The problem "Count Primes" focuses on determining the number of prime numbers less than a non-negative number, limit. The provided Python3 solution implements an efficient algorithm to solve this problem.

  • Initialize the solution that checks for prime numbers up to a given limit. If the limit is 2 or less, the function directly returns 0 because there are no prime numbers less than 2.
  • Manage a list is_prime initialized with boolean values. True signifies prime status. Specifically, positions corresponding to numbers 0 and 1 are set to False as they are not prime.
  • Utilize the Sieve of Eratosthenes algorithm:
    • Iterate over each number starting from 2 up to the square root plus one of the limit. The square root comparison ensures optimizations in marking non-prime numbers.
    • For each number found to still be marked as True (indicating it's a prime), mark its multiples as False (indicating they are not prime) starting from the square of the number (which is the smallest multiple that hasn’t already been marked from a lesser prime) up to the limit, incrementing by the number itself.
  • Count and return all True values in the is_prime list which correspond to prime numbers.

This approach efficiently reduces the problem's complexity by not revisiting multiples of known primes and is well-suited for large values of limit.

Comments

No comments yet.