Open In App

Count Primes in Ranges

Last Updated : 24 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a 2d array queries[][] of size n, where each query queries[i] contain 2 elements [l, r], your task is to find the count of number of primes in inclusive range [l, r]

Examples: 

Input: queries[][] = [ [1, 10], [5, 10], [11, 20] ]
Output: 4 2 4
Explanation: For query 1, number of primes in range [1, 10] are 4 (2, 3, 5, 7).
For query 2, number of primes in range [5, 10] are 2 (5, 7).
For query 3, number of primes in range [11, 20] are 4 (11, 13, 17, 19).

[Naive Approach] - O(n * (r - l + 1) * r1/2) Time and O(1) Space

The idea is to answer each query by iterating through every integer in the specified range [L, R], using a primality check to identify primes, and accumulating the total number of primes found.

Please note that r1/2 is an upper bound for checking prime status of numbers from l to r.

Follow the below given steps:

  • Implement a function isPrime(n) that returns false if n ≤ 1, otherwise checks divisibility from 2 up to √n and returns false on the first divisor found, or true if none are found.
  • In solveQueries, create an empty list results to hold the prime counts for each query.
  • For each query [l, r] in the list of queries:
    • Initialize count = 0.
    • For j from l to r inclusive, call isPrime(j); if it returns true, increment count.
    • After the loop, append count to results.
  • Return results containing the prime counts for all queries.

Below is given the implementation:

C++
#include <bits/stdc++.h>
using namespace std;

// Function to check if a number is prime
bool isPrime(int n) {
    if(n <= 1) return false;
    for(int i = 2; i * i <= n; i++) {
        if(n % i == 0) return false;
    }
    return true;
}

// function to solve the queries
vector<int> solveQueries(vector<vector<int>>& queries) {
    int n = queries.size();

    // to store the results
    vector<int> results;

    for(int i = 0; i < n; i++) {
        int l = queries[i][0];
        int r = queries[i][1];
        int count = 0;

        // Count the prime numbers in the range [l, r]
        for(int j = l; j <= r; j++) {
            if(isPrime(j)) {
                count++;
            }
        }

        // Store the result for this query
        results.push_back(count);
    }
    return results;
}

int main() {
    vector<vector<int>> queries = { {1, 10}, {5, 10}, {11, 20} };
    vector<int> res = solveQueries(queries);
    for(auto i: res) {
        cout << i << " ";
    }
    return 0;
}
Java
import java.util.*;

class GfG {

    public static boolean isPrime(int n) {
        if(n <= 1) return false;
        for(int i = 2; i * i <= n; i++) {
            if(n % i == 0) return false;
        }
        return true;
    }

    public static ArrayList<Integer> solveQueries(ArrayList<ArrayList<Integer>> queries) {
        int n = queries.size();

        // to store the results
        ArrayList<Integer> results = new ArrayList<>();

        for (int i = 0; i < n; i++) {
            int l = queries.get(i).get(0);
            int r = queries.get(i).get(1);
            int count = 0;

            // Count the prime numbers in the range [l, r]
            for (int j = l; j <= r; j++) {
                if (isPrime(j)) {
                    count++;
                }
            }

            // Store the result for this query
            results.add(count);
        }
        return results;
    }

    public static void main(String[] args) {
        ArrayList<ArrayList<Integer>> queries = new ArrayList<>(Arrays.asList(
            new ArrayList<>(Arrays.asList(1, 10)),
            new ArrayList<>(Arrays.asList(5, 10)),
            new ArrayList<>(Arrays.asList(11, 20))
        ));
        ArrayList<Integer> res = solveQueries(queries);
        for (int i : res) {
            System.out.print(i + " ");
        }
    }
}
Python
def isPrime(n):
    if n <= 1:
        return False
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True

def solveQueries(queries):
    n = len(queries)

    # to store the results
    results = []

    for i in range(n):
        l = queries[i][0]
        r = queries[i][1]
        count = 0

        # Count the prime numbers in the range [l, r]
        for j in range(l, r + 1):
            if isPrime(j):
                count += 1

        # Store the result for this query
        results.append(count)
    return results

if __name__ == "__main__":
    queries = [[1, 10], [5, 10], [11, 20]]
    res = solveQueries(queries)
    for i in res:
        print(i, end=" ")
C#
using System;
using System.Collections.Generic;

class GfG {

    public static bool isPrime(int n) {
        if(n <= 1) return false;
        for(int i = 2; i * i <= n; i++) {
            if(n % i == 0) return false;
        }
        return true;
    }

    public static List<int> solveQueries(List<List<int>> queries) {
        int n = queries.Count;

        // to store the results
        List<int> results = new List<int>();

        for (int i = 0; i < n; i++) {
            int l = queries[i][0];
            int r = queries[i][1];
            int count = 0;

            // Count the prime numbers in the range [l, r]
            for (int j = l; j <= r; j++) {
                if (isPrime(j)) {
                    count++;
                }
            }

            // Store the result for this query
            results.Add(count);
        }
        return results;
    }

    public static void Main() {
        List<List<int>> queries = new List<List<int>> {
            new List<int> {1, 10},
            new List<int> {5, 10},
            new List<int> {11, 20}
        };
        List<int> res = solveQueries(queries);
        foreach (var i in res) {
            Console.Write(i + " ");
        }
    }
}
JavaScript
function isPrime(n) {
    if(n <= 1) return false;
    for (let i = 2; i * i <= n; i++) {
        if (n % i == 0) return false;
    }
    return true;
}

function solveQueries(queries) {
    let n = queries.length;

    // to store the results
    let results = [];

    for (let i = 0; i < n; i++) {
        let l = queries[i][0];
        let r = queries[i][1];
        let count = 0;

        // Count the prime numbers in the range [l, r]
        for (let j = l; j <= r; j++) {
            if (isPrime(j)) {
                count++;
            }
        }

        // Store the result for this query
        results.push(count);
    }
    return results;
}

let queries = [[1, 10], [5, 10], [11, 20]];
let res = solveQueries(queries);
for (let i of res) {
    process.stdout.write(i + " ");
}

Output
4 2 4 

[Expected Approach] - Using Sieve of Eratosthenes - O(maxR * log (log maxR))) Time and O(n) Space

The idea is to precompute all primes up to the maximum query endpoint using the Sieve of Eratosthenes, then build a prefix-sum array of prime counts so that each range query can be answered in O(1) time by taking the difference of two prefix values. 

Here maxR the maximum value in queries.

Follow the below given steps:

  • Determine the largest right endpoint maxR among all queries.
  • Run the Sieve of Eratosthenes up to maxR to create a boolean array primes[] where primes[i] is 1 if i is prime, 0 otherwise.
  • Convert primes[] into a prefix-sum array so that primes[i] holds the count of primes from 0 to i.
  • For each query [l, r], compute the answer as primes[r] - primes[l - 1] and store it in the results list.
  • Return the list of results for all queries.

Below is given the implementation:

C++
#include <bits/stdc++.h>
using namespace std;

// Function to find all prime numbers 
// up to n using Sieve of Eratosthenes
vector<int> findPrimes(int n) {
    vector<int> primes(n + 1, 1);
    
    // 0 and 1 are not prime numbers
    primes[0] = primes[1] = 0; 

    for(int i = 2; i * i <= n; i++) {
        if(primes[i]) {
            for(int j = i * i; j <= n; j += i) {
                primes[j] = 0;
            }
        }
    }
    return primes;
}

// function to solve the queries
vector<int> solveQueries(vector<vector<int>>& queries) {
    int n = queries.size();

    // to store the res
    vector<int> res;

    // Find the maximum value of r in the queries
    int maxR = 0;
    for(int i = 0; i < n; i++) {
        maxR = max(maxR, queries[i][1]);
    }

    // Get the prime numbers up to maxR
    vector<int> primes = findPrimes(maxR);

    // Precompute the prefix sum of prime counts
    for(int i = 1; i <= maxR; i++) {
        primes[i] += primes[i - 1];
    }

    for(int i = 0; i < n; i++) {
        int l = queries[i][0];
        int r = queries[i][1];

        // Count the prime numbers in the range [l, r]
        int count = primes[r] - primes[l - 1];

        // Store the result for this query
        res.push_back(count);
    }
    return res;
}

int main() {
    vector<vector<int>> queries = { {1, 10}, {5, 10}, {11, 20} };
    vector<int> res = solveQueries(queries);
    for(auto i: res) {
        cout << i << " ";
    }
    return 0;
}
Java
import java.util.*;

class GfG {

    public static ArrayList<Integer> findPrimes(int n) {
        ArrayList<Integer> primes = new ArrayList<>(Collections.nCopies(n + 1, 1));

        // 0 and 1 are not prime numbers
        primes.set(0, 0);
        primes.set(1, 0);

        for (int i = 2; i * i <= n; i++) {
            if (primes.get(i) == 1) {
                for (int j = i * i; j <= n; j += i) {
                    primes.set(j, 0);
                }
            }
        }
        return primes;
    }

    public static ArrayList<Integer> solveQueries(ArrayList<ArrayList<Integer>> queries) {
        int n = queries.size();

        // to store the res
        ArrayList<Integer> res = new ArrayList<>();

        // Find the maximum value of r in the queries
        int maxR = 0;
        for (int i = 0; i < n; i++) {
            maxR = Math.max(maxR, queries.get(i).get(1));
        }

        // Get the prime numbers up to maxR
        ArrayList<Integer> primes = findPrimes(maxR);

        // Precompute the prefix sum of prime counts
        for (int i = 1; i <= maxR; i++) {
            primes.set(i, primes.get(i) + primes.get(i - 1));
        }

        for (int i = 0; i < n; i++) {
            int l = queries.get(i).get(0);
            int r = queries.get(i).get(1);

            // Count the prime numbers in the range [l, r]
            int count = primes.get(r) - primes.get(l - 1);

            // Store the result for this query
            res.add(count);
        }
        return res;
    }

    public static void main(String[] args) {
        ArrayList<ArrayList<Integer>> queries = new ArrayList<>();
        queries.add(new ArrayList<>(Arrays.asList(1, 10)));
        queries.add(new ArrayList<>(Arrays.asList(5, 10)));
        queries.add(new ArrayList<>(Arrays.asList(11, 20)));
        ArrayList<Integer> res = solveQueries(queries);
        for (int i : res) {
            System.out.print(i + " ");
        }
    }
}
Python
def findPrimes(n):
    primes = [1] * (n + 1)

    # 0 and 1 are not prime numbers
    primes[0] = primes[1] = 0

    for i in range(2, int(n**0.5) + 1):
        if primes[i]:
            for j in range(i * i, n + 1, i):
                primes[j] = 0
    return primes

def solveQueries(queries):
    n = len(queries)

    # to store the res
    res = []

    # Find the maximum value of r in the queries
    maxR = 0
    for i in range(n):
        maxR = max(maxR, queries[i][1])

    # Get the prime numbers up to maxR
    primes = findPrimes(maxR)

    # Precompute the prefix sum of prime counts
    for i in range(1, maxR + 1):
        primes[i] += primes[i - 1]

    for i in range(n):
        l = queries[i][0]
        r = queries[i][1]

        # Count the prime numbers in the range [l, r]
        count = primes[r] - primes[l - 1]

        # Store the result for this query
        res.append(count)
    return res

if __name__ == "__main__":
    queries = [[1, 10], [5, 10], [11, 20]]
    res = solveQueries(queries)
    for i in res:
        print(i, end=" ")
C#
using System;
using System.Collections.Generic;
using System.Linq;

class GfG {

    public static List<int> findPrimes(int n) {
        List<int> primes = Enumerable.Repeat(1, n + 1).ToList();

        // 0 and 1 are not prime numbers
        primes[0] = 0;
        primes[1] = 0;

        for (int i = 2; i * i <= n; i++) {
            if (primes[i] == 1) {
                for (int j = i * i; j <= n; j += i) {
                    primes[j] = 0;
                }
            }
        }
        return primes;
    }

    public static List<int> solveQueries(List<List<int>> queries) {
        int n = queries.Count;

        // to store the res
        List<int> res = new List<int>();

        // Find the maximum value of r in the queries
        int maxR = 0;
        for (int i = 0; i < n; i++) {
            maxR = Math.Max(maxR, queries[i][1]);
        }

        // Get the prime numbers up to maxR
        List<int> primes = findPrimes(maxR);

        // Precompute the prefix sum of prime counts
        for (int i = 1; i <= maxR; i++) {
            primes[i] += primes[i - 1];
        }

        for (int i = 0; i < n; i++) {
            int l = queries[i][0];
            int r = queries[i][1];

            // Count the prime numbers in the range [l, r]
            int count = primes[r] - primes[l - 1];

            // Store the result for this query
            res.Add(count);
        }
        return res;
    }

    public static void Main() {
        List<List<int>> queries = new List<List<int>> {
            new List<int> {1, 10},
            new List<int> {5, 10},
            new List<int> {11, 20}
        };
        List<int> res = solveQueries(queries);
        foreach (var i in res) {
            Console.Write(i + " ");
        }
    }
}
JavaScript
function findPrimes(n) {
    let primes = Array(n + 1).fill(1);

    // 0 and 1 are not prime numbers
    primes[0] = primes[1] = 0;

    for (let i = 2; i * i <= n; i++) {
        if (primes[i]) {
            for (let j = i * i; j <= n; j += i) {
                primes[j] = 0;
            }
        }
    }
    return primes;
}

function solveQueries(queries) {
    let n = queries.length;

    // to store the res
    let res = [];

    // Find the maximum value of r in the queries
    let maxR = 0;
    for (let i = 0; i < n; i++) {
        maxR = Math.max(maxR, queries[i][1]);
    }

    // Get the prime numbers up to maxR
    let primes = findPrimes(maxR);

    // Precompute the prefix sum of prime counts
    for (let i = 1; i <= maxR; i++) {
        primes[i] += primes[i - 1];
    }

    for (let i = 0; i < n; i++) {
        let l = queries[i][0];
        let r = queries[i][1];

        // Count the prime numbers in the range [l, r]
        let count = primes[r] - primes[l - 1];

        // Store the result for this query
        res.push(count);
    }
    return res;
}

let queries = [[1, 10], [5, 10], [11, 20]];
let res = solveQueries(queries);
for (let i of res) {
    process.stdout.write(i + " ");
}

Output
4 2 4 

Next Article

Similar Reads