LeetCode 204: Count Primes Solution in Python Explained

Prime numbers have a timeless allure, and LeetCode 204: Count Primes is an easy-level problem that lets you explore them in a practical way! In this challenge, you’re given an integer n, and your task is to count how many prime numbers are less than n. A prime number is a natural number greater than 1 with exactly two distinct factors: 1 and itself. Using Python, we’ll dive into two solutions: Sieve of Eratosthenes (our best solution) and Trial Division (a simple alternative). With step-by-step examples, detailed code breakdowns, and beginner-friendly insights, you’ll master prime counting. Let’s embark on this mathematical journey!

Problem Statement

Section link icon

In LeetCode 204: Count Primes, you’re given:

  • An integer n where 0 ≤ n ≤ 5 * 10⁶.
  • Your task is to return the number of prime numbers strictly less than n.

For example, if n = 10, the primes are 2, 3, 5, 7, so the answer is 4. This differs from linked list problems like LeetCode 203: Remove Linked List Elements, focusing instead on number theory and optimization.

Constraints

  • 0 ≤ n ≤ 5 * 10⁶.

Examples

Let’s see some cases:

Input: n = 10
Output: 4
Explanation: Primes < 10 are 2, 3, 5, 7 (4 primes).
Input: n = 0
Output: 0
Explanation: No primes less than 0.
Input: n = 2
Output: 0
Explanation: No primes less than 2 (2 itself is not counted).

These examples clarify that we’re counting primes below n.

Understanding the Problem

Section link icon

How do we solve LeetCode 204: Count Primes in Python? For n = 10, we need to identify 2, 3, 5, 7. A naive approach might test each number up to n for primality, but that’s slow for large n. This isn’t a cycle detection problem like LeetCode 202: Happy Number; it’s about efficiently sieving out non-primes. We’ll use: 1. Sieve of Eratosthenes: O(n log log n) time, O(n) space—our best solution. 2. Trial Division: O(n * sqrt(n)) time, O(1) space—an alternative.

Let’s explore the best solution.

Best Solution: Sieve of Eratosthenes Approach

Section link icon

Explanation

The Sieve of Eratosthenes is a classic algorithm to find all primes up to n:

  • Create a boolean array is_prime from 0 to n-1, initially all True.
  • Set 0 and 1 to False (not prime).
  • For each prime i, mark its multiples as False (not prime).
  • Count the remaining True values.

It’s O(n log log n) time (highly efficient for large n) and O(n) space (array size), making it the best solution for this problem.

For n = 10, it marks out 4, 6, 8, 9, leaving 2, 3, 5, 7.

Step-by-Step Example

Example 1: n = 10

Goal: Return 4.

  • Step 1: Initialize.
    • is_prime = [True] * 10 (0 to 9).
    • is_prime[0] = is_prime[1] = False.
    • count = 0.
  • Step 2: Sieve.
    • i = 2: Prime, mark multiples:
      • 4, 6, 8False.
      • is_prime = [F, F, T, T, F, T, F, T, F, T].
    • i = 3: Prime, mark multiples:
      • 6, 9False (6 already False).
      • is_prime = [F, F, T, T, F, T, F, T, F, F].
    • i = 4: False, skip.
    • i = 5: Prime, mark 10 (out of range), stop at sqrt(10) ≈ 3.
  • Step 3: Count.
    • is_prime[2:] = [T, T, F, T, F, T, F, F].
    • Count True: 2, 3, 5, 74.
  • Output: 4.

Example 2: n = 5

Goal: Return 3.

  • Step 1: is_prime = [T, T, T, T, T], set 0, 1 to F.
  • Step 2:
    • i = 2: Mark 4F.
    • i = 3: No multiples < 5.
  • Step 3: [F, F, T, T, F], count 2, 33.
  • Output: 3.

How the Code Works (Sieve of Eratosthenes) – Detailed Line-by-Line Explanation

Here’s the Python code with a detailed breakdown:

def countPrimes(n: int) -> int:
    # Line 1: Handle edge cases
    if n <= 2:
        # No primes less than 2 (e.g., n = 0, 1, 2)
        return 0

    # Line 2: Initialize sieve array
    is_prime = [True] * n
    # Array of n Trues (e.g., [T, T, T, T, T] for n=5)
    is_prime[0] = is_prime[1] = False
    # 0 and 1 are not prime (e.g., [F, F, T, T, T])

    # Line 3: Mark non-primes using sieve
    for i in range(2, int(n ** 0.5) + 1):
        # Up to sqrt(n) (e.g., i = 2, 3 for n=10)
        if is_prime[i]:
            # If i is prime (e.g., i = 2)
            for j in range(i * i, n, i):
                # Mark multiples (e.g., 4, 6, 8)
                is_prime[j] = False
                # Set to False (e.g., is_prime[4] = F)

    # Line 4: Count primes
    return sum(is_prime)
    # Sum Trues (e.g., [F, F, T, T, F, T, F, T, F, F] → 4)

This solution is both elegant and optimized.

Alternative: Trial Division Approach

Section link icon

Explanation

The Trial Division approach checks each number for primality:

  • For each i from 2 to n-1, test if it’s prime by checking divisors up to sqrt(i).
  • Increment a counter for each prime found.

It’s O(n * sqrt(n)) time (slow for large n) and O(1) space, making it a simple but less efficient alternative.

Step-by-Step Example

For n = 10:

  • 2: Prime (no divisors), count = 1.
  • 3: Prime, count = 2.
  • 4: Divisible by 2, skip.
  • 5: Prime, count = 3.
  • 6, 8: Not prime.
  • 7: Prime, count = 4.
  • 9: Divisible by 3, skip.
  • Output: 4.

How the Code Works (Trial Division)

def countPrimesTrial(n: int) -> int:
    def is_prime(num):
        if num < 2:
            return False
        for i in range(2, int(num ** 0.5) + 1):
            if num % i == 0:
                return False
        return True

    count = 0
    for i in range(2, n):
        if is_prime(i):
            count += 1
    return count

Complexity

  • Sieve of Eratosthenes:
    • Time: O(n log log n) – efficient sieving.
    • Space: O(n) – array size.
  • Trial Division:
    • Time: O(n * sqrt(n)) – checks each number.
    • Space: O(1) – no extra space.

Efficiency Notes

Sieve of Eratosthenes is our best solution with near-linear time and scalability. Trial Division is intuitive but impractical for large n.

Key Insights

  • Sieve: Eliminates multiples efficiently.
  • Prime: Only 2 factors.
  • Optimization: Sqrt bound.

Additional Example

Section link icon

For n = 15:

  • Sieve: 2, 3, 5, 7, 11, 136.
  • Trial: Same result, slower.

Edge Cases

Section link icon
  • n = 0, 1, 2: 0 (no primes).
  • n = 3: 1 (just 2).

Both handle these well.

Final Thoughts

Section link icon

LeetCode 204: Count Primes in Python is a fantastic dive into prime numbers. Sieve of Eratosthenes shines with efficiency, while Trial Division offers simplicity. Want more? Try LeetCode 263: Ugly Number or LeetCode 191: Number of 1 Bits. Test your skills—Solve LeetCode 204 on LeetCode with n = 10 (expecting 4)—count those primes today!