Count Frequency of an Element in a Given Range

Last Updated : 16 Jul, 2025

Given an array arr[] of integers and a 2D array queries[][], where each queries[i] contains three integers: l, r, and x. For each query, determine how many times the element x appears in the subarray of arr[] from index l to r (both inclusive).
For each query, return the count of occurrences of x in the specified range.

Examples:

Input: arr []= [1, 2, 1, 3, 1, 2, 3], queries[][] = [[0, 4, 1], [2, 5, 2], [1, 6, 3], [0, 6, 5]]
Output: [3, 1, 2, 0]
Explanation:
query [0, 4, 1] → Subarray = [1, 2, 1, 3, 1], 1 appears 3 times
query [2, 5, 2] → Subarray = [1, 3, 1, 2], 2 appears 1 time
query [1, 6, 3] → Subarray = [2, 1, 3, 1, 2, 3] 3 appears 2 times
query [0, 6, 5] → Subarray = [1, 2, 1, 3, 1, 2, 3], 5 appears 0 times

Input: arr[] = [11, 21, 51, 101, 11, 51], queries[][] = [[0, 4, 11], [2, 5, 51]]
Output: [2, 2]
Explanation:
query [0, 4, 11] → Subarray = [11, 21, 51, 101, 11], 11 appears 2 times
query [2, 5, 51] → Subarray = [51, 101, 11, 51], 51 appears 2 times

Try It Yourself
redirect icon

[Naive Approach] Range Frequency Scan - O(n × q) Time and O(1) Space

The idea is to iterate over each query and scan the subarray from index l to r, counting how many times the element x appears. This is done using a simple linear loop for every query without any preprocessing.

C++
#include <iostream>
#include <vector>
using namespace std;

vector<int> freqInRange(vector<int>& arr, 
                        vector<vector<int>>& queries) {
    vector<int> result;

    // process each query
    for (auto& q : queries) {
        int l = q[0];
        int r = q[1];
        int x = q[2];
        int count = 0;

        // loop from l to r and count how many 
        // times x appears
        for (int i = l; i <= r; ++i) {
            if (arr[i] == x) {
                count++;
            }
        }

        // store the answer for this query
        result.push_back(count);
    }

    return result;
}

int main() {
    vector<int> arr = {1, 2, 1, 3, 1, 2, 3};
    vector<vector<int>> queries = {
        {0, 4, 1},
        {2, 5, 2},
        {1, 6, 3},
        {0, 6, 5}
    };

    vector<int> ans = freqInRange(arr, queries);

    for (int val : ans) {
        cout << val << " ";
    }
    cout << endl;

    return 0;
}
Java
import java.util.ArrayList;

class GfG {
    static ArrayList<Integer> freqInRange(int[] arr, 
                                        int[][] queries) {
        ArrayList<Integer> result = new ArrayList<>();

        // process each query
        for (int[] q : queries) {
            int l = q[0];
            int r = q[1];
            int x = q[2];
            int count = 0;

            // loop from l to r and count how many 
            // times x appears
            for (int i = l; i <= r; ++i) {
                if (arr[i] == x) {
                    count++;
                }
            }

            // store the answer for this query
            result.add(count);
        }

        return result;
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 1, 3, 1, 2, 3};
        int[][] queries = {
            {0, 4, 1},
            {2, 5, 2},
            {1, 6, 3},
            {0, 6, 5}
        };

        ArrayList<Integer> ans = freqInRange(arr, queries);

        for (int val : ans) {
            System.out.print(val + " ");
        }
        System.out.println();
    }
}
Python
def freqInRange(arr, queries):
    result = []

    # process each query
    for q in queries:
        l = q[0]
        r = q[1]
        x = q[2]
        count = 0

        # loop from l to r and count how many 
        # times x appears
        for i in range(l, r + 1):
            if arr[i] == x:
                count += 1

        # store the answer for this query
        result.append(count)

    return result


if __name__ == "__main__":
    arr = [1, 2, 1, 3, 1, 2, 3]
    queries = [
        [0, 4, 1],
        [2, 5, 2],
        [1, 6, 3],
        [0, 6, 5]
    ]

    ans = freqInRange(arr, queries)
    print(*ans)
C#
using System;
using System.Collections.Generic;

class GfG {
    static List<int> freqInRange(int[] arr, 
                            List<int[]> queries) {
        List<int> result = new List<int>();

        // process each query
        foreach (var q in queries) {
            int l = q[0];
            int r = q[1];
            int x = q[2];
            int count = 0;

            // loop from l to r and count how many 
            // times x appears
            for (int i = l; i <= r; ++i) {
                if (arr[i] == x) {
                    count++;
                }
            }

            // store the answer for this query
            result.Add(count);
        }

        return result;
    }

    static void Main() {
        int[] arr = {1, 2, 1, 3, 1, 2, 3};
        List<int[]> queries = new List<int[]> {
            new int[] {0, 4, 1},
            new int[] {2, 5, 2},
            new int[] {1, 6, 3},
            new int[] {0, 6, 5}
        };

        List<int> ans = freqInRange(arr, queries);

        foreach (int val in ans) {
            Console.Write(val + " ");
        }
        Console.WriteLine();
    }
}
JavaScript
function freqInRange(arr, queries) {
    let result = [];

    // process each query
    for (let q of queries) {
        let l = q[0];
        let r = q[1];
        let x = q[2];
        let count = 0;

        // loop from l to r and count how many 
        // times x appears
        for (let i = l; i <= r; i++) {
            if (arr[i] === x) {
                count++;
            }
        }

        // store the answer for this query
        result.push(count);
    }

    return result;
}

// Driver Code
let arr = [1, 2, 1, 3, 1, 2, 3];
let queries = [
    [0, 4, 1],
    [2, 5, 2],
    [1, 6, 3],
    [0, 6, 5]
];

let ans = freqInRange(arr, queries);
console.log(ans.join(" "));

Output
3 1 2 0 

[Expected Approach] Indexed Map and Binary Search

The idea is to precompute the positions of each element in the array and store them in a map. For each query, we find how many times x appears between indices l and r by applying lower_bound and upper_bound on the stored index list of x.

Step by Step Implementation:

  • Build a map from each element value to a list of its indices. Loop through the array and for every value val, append its index i to indexMap[val].
  • For each query [l, r, x]:
    - If x is not present in the map, add 0 to the result and continue.
    - Otherwise:
    => Retrieve the sorted list of indices for value x from the map.
    => Use binary search (lower_bound) to find the first index ≥ l.
    => Use binary search (upper_bound) to find the first index > r.
    => The number of occurrences of x in range [l, r] is right - left.
C++
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;

vector<int> freqInRange(vector<int>& arr, 
                    vector<vector<int>>& queries) {
    map<int, vector<int>> indexMap;

    // store all indices of each value in the map
    for (int i = 0; i < arr.size(); ++i) {
        indexMap[arr[i]].push_back(i);
    }

    vector<int> result;

    // process each query
    for (auto& q : queries) {
        int l = q[0];
        int r = q[1];
        int x = q[2];

        // if x does not exist in map, frequency is 0
        if (indexMap.find(x) == indexMap.end()) {
            result.push_back(0);
            continue;
        }

        // get index list of x
        vector<int>& ind = indexMap[x];

        // count occurrences between l and r
        // using binary search
        auto left = 
                lower_bound(ind.begin(), ind.end(), l);
        auto right = 
                upper_bound(ind.begin(), ind.end(), r);

        // number of occurrences is difference of bounds
        result.push_back(right - left);
    }

    return result;
}

int main() {
    vector<int> arr = {1, 2, 1, 3, 1, 2, 3};
    vector<vector<int>> queries = {
        {0, 4, 1},
        {2, 5, 2},
        {1, 6, 3},
        {0, 6, 5}
    };

    vector<int> ans = freqInRange(arr, queries);

    for (int val : ans) {
        cout << val << " ";
    }
    cout << endl;

    return 0;
}
Java
import java.util.*;

class GfG {
    // process frequency queries using map 
    //  and binary search
    public static ArrayList<Integer> 
                    freqInRange(int[] arr, int[][] queries) {
        Map<Integer, ArrayList<Integer>> indexMap = 
                                            new HashMap<>();

        // store all indices of each value in the map
        for (int i = 0; i < arr.length; i++) {
            indexMap.putIfAbsent(arr[i], new ArrayList<>());
            indexMap.get(arr[i]).add(i);
        }

        ArrayList<Integer> result = new ArrayList<>();

        // process each query
        for (int[] q : queries) {
            int l = q[0];
            int r = q[1];
            int x = q[2];

            // if x does not exist in map, frequency is 0
            if (!indexMap.containsKey(x)) {
                result.add(0);
                continue;
            }

            ArrayList<Integer> ind = indexMap.get(x);

            // count occurrences between l and r 
            // using binary search
            int left = 
                Collections.binarySearch(ind, l);
            int right = 
                Collections.binarySearch(ind, r + 1);

            if (left < 0) left = -(left + 1);
            if (right < 0) right = -(right + 1);

            // number of occurrences is difference 
            // of bounds
            result.add(right - left);
        }

        return result;
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 1, 3, 1, 2, 3};
        int[][] queries = {
            {0, 4, 1},
            {2, 5, 2},
            {1, 6, 3},
            {0, 6, 5}
        };

        ArrayList<Integer> ans = freqInRange(arr, queries);
        for (int val : ans) {
            System.out.print(val + " ");
        }
        System.out.println();
    }
}
Python
import bisect

def freqInRange(arr, queries):
    indexMap = {}

    # store all indices of each value in the map
    for i, val in enumerate(arr):
        if val not in indexMap:
            indexMap[val] = []
        indexMap[val].append(i)

    result = []

    # process each query
    for q in queries:
        l, r, x = q

        # if x does not exist in map, frequency is 0
        if x not in indexMap:
            result.append(0)
            continue

        ind = indexMap[x]

        # count occurrences between l and r 
        # using binary search
        left = bisect.bisect_left(ind, l)
        right = bisect.bisect_right(ind, r)

        # number of occurrences is difference of bounds
        result.append(right - left)

    return result

if __name__ == "__main__":
    arr = [1, 2, 1, 3, 1, 2, 3]
    queries = [
        [0, 4, 1],
        [2, 5, 2],
        [1, 6, 3],
        [0, 6, 5]
    ]

    ans = freqInRange(arr, queries)
    print(*ans)
C#
using System;
using System.Collections.Generic;

class GfG {
    // process frequency queries using map and
    // binary search
    static List<int> freqInRange(int[] arr, 
                                List<int[]> queries) {
        Dictionary<int, List<int>> indexMap = 
                    new Dictionary<int, List<int>>();

        // store all indices of each value in the map
        for (int i = 0; i < arr.Length; i++) {
            if (!indexMap.ContainsKey(arr[i]))
                indexMap[arr[i]] = new List<int>();
            indexMap[arr[i]].Add(i);
        }

        List<int> result = new List<int>();

        // process each query
        foreach (var q in queries) {
            int l = q[0];
            int r = q[1];
            int x = q[2];

            // if x does not exist in map, frequency is 0
            if (!indexMap.ContainsKey(x)) {
                result.Add(0);
                continue;
            }

            List<int> ind = indexMap[x];

            // count occurrences between l and r
            // using binary search
            int left = ind.BinarySearch(l);
            int right = ind.BinarySearch(r + 1);

            if (left < 0) left = ~left;
            if (right < 0) right = ~right;

            // number of occurrences is difference
            // of bounds
            result.Add(right - left);
        }

        return result;
    }

    static void Main() {
        int[] arr = {1, 2, 1, 3, 1, 2, 3};
        List<int[]> queries = new List<int[]> {
            new int[] {0, 4, 1},
            new int[] {2, 5, 2},
            new int[] {1, 6, 3},
            new int[] {0, 6, 5}
        };

        List<int> ans = freqInRange(arr, queries);
        foreach (int val in ans) Console.Write(val + " ");
        Console.WriteLine();
    }
}
JavaScript
// helper binary search functions
function lowerBound(arr, target) {
    let low = 0, high = arr.length;
    while (low < high) {
        let mid = Math.floor((low + high) / 2);
        if (arr[mid] < target) low = mid + 1;
        else high = mid;
    }
    return low;
}

function upperBound(arr, target) {
    let low = 0, high = arr.length;
    while (low < high) {
        let mid = Math.floor((low + high) / 2);
        if (arr[mid] <= target) low = mid + 1;
        else high = mid;
    }
    return low;
}

// function to process frequency queries using map 
// and binary search
function freqInRange(arr, queries) {
    let indexMap = new Map();

    // store all indices of each value in the map
    for (let i = 0; i < arr.length; i++) {
        if (!indexMap.has(arr[i])) {
            indexMap.set(arr[i], []);
        }
        indexMap.get(arr[i]).push(i);
    }

    let result = [];

    // process each query
    for (let q of queries) {
        let l = q[0], r = q[1], x = q[2];

        // if x does not exist in map, frequency is 0
        if (!indexMap.has(x)) {
            result.push(0);
            continue;
        }

        let ind = indexMap.get(x);

        // count occurrences between l and r using 
        // binary search
        let left = lowerBound(ind, l);
        let right = upperBound(ind, r);

        // number of occurrences is difference
        // of bounds
        result.push(right - left);
    }

    return result;
}

// Driver Code
let arr = [1, 2, 1, 3, 1, 2, 3];
let queries = [
    [0, 4, 1],
    [2, 5, 2],
    [1, 6, 3],
    [0, 6, 5]
];

let ans = freqInRange(arr, queries);
console.log(ans.join(" "));

Output
3 1 2 0 

Time Complexity: O(n × logn + q × log k), preprocessing the map takes O(n × log n) time, where n is the size of the array then for each of the q queries, we perform two binary searches on the index list of size k (number of times x appears), costing O(log k) per query.
Auxiliary Space: O(n), we use a map to store indices of each distinct element. In the worst case (all elements unique), the total space used across all vectors is proportional to the array size n.

Comment