Count of Strings of Array having given prefixes for Q query

Last Updated : 2 Jul, 2026

Given an array of strings s[] and an array of query strings q[], where all strings consist of lowercase English letters, determine for each query string q[i] the number of strings in s[] that have q[i] as a prefix. Return an array res[] such that res[i] denotes the number of strings in s[] that begin with the prefix q[i].

Examples:

Input: s[] = ["abracadabra", "geeksforgeeks", "abracadabra", "geeks", "geeksthrill"], q[] = ["abr", "geeks", "ge", "gar"]
Output: [2, 3, 3, 0]
Explanation: For each query:  
"abr" is a prefix of both occurrences of "abracadabra", so the count is 2.
"geeks" is a prefix of "geeksforgeeks", "geeks", and "geeksthrill", so the count is 3.
"ge" is a prefix of "geeksforgeeks", "geeks", and "geeksthrill", so the count is 3.
"gar" is not a prefix of any string in s[], so the count is 0.

Input: s[] = ["apple", "app", "banana", "application"], q[] = ["ap", "ban"]
Output: [3, 1]
Explanation: For each query: 
"ap" is a prefix of "apple", "app", and "application", so the count is 3.
"ban" is a prefix of "banana", so the count is 1.

Try It Yourself
redirect icon

[Naive Approach] Check Every Query Against Every String - O(Q * N * L) Time and O(1) Space

The idea is to process each query independently. For every query string, traverse all strings in the array and check whether the query is a prefix of the current string. Count all such matches and store the result.

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

// Checks if pref is a prefix of str.
bool isPrefix(string &str, string &pref)
{
    if (pref.size() > str.size())
        return false;

    for (int i = 0; i < pref.size(); i++)
    {
        if (str[i] != pref[i])
            return false;
    }

    return true;
}

vector<int> prefCount(vector<string> &s, vector<string> &q)
{
    vector<int> res;

    // Process each query independently.
    for (string &pref : q)
    {

        int cnt = 0;

        // Check every string.
        for (string &str : s)
        {
            if (isPrefix(str, pref))
                cnt++;
        }

        res.push_back(cnt);
    }

    return res;
}

// Driver code
int main()
{
    vector<string> s = {"abracadabra", "geeksforgeeks", "abracadabra", "geeks", "geeksthrill"};

    vector<string> q = {"abr", "geeks", "ge", "gar"};

    vector<int> res = prefCount(s, q);

    cout << "[";

    for (int i = 0; i < res.size(); i++)
    {
        cout << res[i];

        if (i != res.size() - 1)
            cout << ", ";
    }

    cout << "]";

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

// Checks if pref is a prefix of str.
class GFG {
    static boolean isPrefix(String str, String pref)
    {
        if (pref.length() > str.length())
            return false;

        for (int i = 0; i < pref.length(); i++) {
            if (str.charAt(i) != pref.charAt(i))
                return false;
        }

        return true;
    }

    static ArrayList<Integer> prefCount(ArrayList<String> s,
                                        ArrayList<String> q)
    {
        ArrayList<Integer> res = new ArrayList<>();

        // Process each query independently.
        for (String pref : q) {

            int cnt = 0;

            // Check every string.
            for (String str : s) {
                if (isPrefix(str, pref))
                    cnt++;
            }

            res.add(cnt);
        }

        return res;
    }

    // Driver code
    public static void main(String[] args)
    {
        ArrayList<String> s = new ArrayList<>(Arrays.asList(
            "abracadabra", "geeksforgeeks", "abracadabra",
            "geeks", "geeksthrill"));

        ArrayList<String> q = new ArrayList<>(
            Arrays.asList("abr", "geeks", "ge", "gar"));

        ArrayList<Integer> res = prefCount(s, q);

        System.out.print("[");

        for (int i = 0; i < res.size(); i++) {
            System.out.print(res.get(i));

            if (i != res.size() - 1)
                System.out.print(", ");
        }

        System.out.print("]");
    }
}
Python
# Checks if pref is a prefix of str.
def isPrefix(str, pref):
    if len(pref) > len(str):
        return False

    for i in range(len(pref)):
        if str[i] != pref[i]:
            return False

    return True


def prefCount(s, q):
    res = []

    # Process each query independently.
    for pref in q:

        cnt = 0

        # Check every string.
        for str in s:
            if isPrefix(str, pref):
                cnt += 1

        res.append(cnt)

    return res


# Driver code
if __name__ == "__main__":
    s = ["abracadabra", "geeksforgeeks", "abracadabra",
         "geeks", "geeksthrill"]

    q = ["abr", "geeks", "ge", "gar"]

    res = prefCount(s, q)

    print("[", end="")

    for i in range(len(res)):
        print(res[i], end="")

        if i != len(res) - 1:
            print(", ", end="")

    print("]", end="")
C#
using System;
using System.Collections.Generic;

class GFG {
    // Checks if pref is a prefix of str.
    static bool isPrefix(string str, string pref)
    {
        if (pref.Length > str.Length)
            return false;

        for (int i = 0; i < pref.Length; i++) {
            if (str[i] != pref[i])
                return false;
        }

        return true;
    }

    static List<int> prefCount(List<string> s,
                               List<string> q)
    {
        List<int> res = new List<int>();

        // Process each query independently.
        foreach(string pref in q)
        {

            int cnt = 0;

            // Check every string.
            foreach(string str in s)
            {
                if (isPrefix(str, pref))
                    cnt++;
            }

            res.Add(cnt);
        }

        return res;
    }

    // Driver code
    static void Main()
    {
        List<string> s = new List<string>{
            "abracadabra", "geeksforgeeks", "abracadabra",
            "geeks", "geeksthrill"
        };

        List<string> q = new List<string>{ "abr", "geeks",
                                           "ge", "gar" };

        List<int> res = prefCount(s, q);

        Console.Write("[");

        for (int i = 0; i < res.Count; i++) {
            Console.Write(res[i]);

            if (i != res.Count - 1)
                Console.Write(", ");
        }

        Console.Write("]");
    }
}
JavaScript
// Checks if pref is a prefix of str.
function isPrefix(str, pref)
{
    if (pref.length > str.length)
        return false;

    for (let i = 0; i < pref.length; i++) {
        if (str[i] !== pref[i])
            return false;
    }

    return true;
}

function prefCount(s, q)
{
    let res = [];

    // Process each query independently.
    for (let pref of q) {

        let cnt = 0;

        // Check every string.
        for (let str of s) {
            if (isPrefix(str, pref))
                cnt++;
        }

        res.push(cnt);
    }

    return res;
}

// Driver code
let s = [
    "abracadabra", "geeksforgeeks", "abracadabra", "geeks",
    "geeksthrill"
];

let q = [ "abr", "geeks", "ge", "gar" ];

let res = prefCount(s, q);

console.log("[");

for (let i = 0; i < res.length; i++) {
    process.stdout.write(res[i].toString());
    if (i != res.length - 1)
        process.stdout.write(", ");
}

console.log("]");

Output
[2, 3, 3, 0]

[Expected Approach] Trie with Prefix Count - O(N * L + Q * L) Time and O(N * L) Space

The idea is to build a Trie using all strings in the array. Each Trie node stores the number of strings passing through it. For a query, traverse the Trie following its characters. If the prefix exists, return the stored count at the last node; otherwise return 0.

Let us understand with example:
Input: s[] = ["abracadabra", "geeksforgeeks", "abracadabra", "geeks", "geeksthrill"], q[] = ["abr", "geeks", "ge", "gar"]

  • Insert all strings into the Trie. While inserting each character, increment the count stored at the corresponding Trie node.
  • For query "abr", traverse the Trie along a -> b -> r. The node for "abr" stores count 2, so the answer is 2.
  • For query "geeks", the traversal reaches the node for "geeks", which stores count 3, so the answer is 3.
  • For query "ge", the node for "ge" stores count 3, so the answer is 3.
  • For query "gar", the required path is not present in the Trie, so the answer is 0.

Output: [2, 3, 3, 0]

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

// Trie node representing a single character.
class TrieNode
{
  public:
    // Number of words having the prefix represented
    // by the path from root to this node.
    int cnt;

    // Pointers to child nodes for characters 'a' to 'z'.
    TrieNode *child[26];

    TrieNode()
    {
        cnt = 0;

        for (int i = 0; i < 26; i++)
        {
            child[i] = nullptr;
        }
    }
};

// Inserts a word into the trie and updates
// the prefix count at each visited node.
void insert(TrieNode *root, string &word)
{
    TrieNode *node = root;

    for (char ch : word)
    {
        int idx = ch - 'a';

        // Create a new node if the path does not exist.
        if (node->child[idx] == nullptr)
        {
            node->child[idx] = new TrieNode();
        }

        node = node->child[idx];

        // Increment the count of words passing
        // through this prefix node.
        node->cnt++;
    }
}

// Returns the number of words that start
// with the given prefix.
int countPref(TrieNode *root, string &pref)
{
    TrieNode *node = root;

    for (char ch : pref)
    {
        int idx = ch - 'a';

        // Prefix not present in the trie.
        if (node->child[idx] == nullptr)
        {
            return 0;
        }

        node = node->child[idx];
    }

    // The stored count equals the number of
    // words having this prefix.
    return node->cnt;
}

vector<int> prefCount(vector<string> &s, vector<string> &q)
{
    // Create the root of the trie.
    TrieNode *root = new TrieNode();

    // Insert all words into the trie.
    for (string &word : s)
    {
        insert(root, word);
    }

    vector<int> res;

    // Answer each query independently.
    for (string &pref : q)
    {
        res.push_back(countPref(root, pref));
    }

    return res;
}

// Driver code
int main()
{
    vector<string> s = {"abracadabra", "geeksforgeeks", "abracadabra", "geeks", "geeksthrill"};

    vector<string> q = {"abr", "geeks", "ge", "gar"};

    vector<int> res = prefCount(s, q);

    cout << "[";

    for (int i = 0; i < res.size(); i++)
    {
        cout << res[i];

        if (i != res.size() - 1)
            cout << ", ";
    }

    cout << "]";

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

// Trie node representing a single character.
class TrieNode {
    // Number of words having the prefix represented
    // by the path from root to this node.
    int cnt;

    // Pointers to child nodes for characters 'a' to 'z'.
    TrieNode[] child;

    TrieNode()
    {
        cnt = 0;
        child = new TrieNode[26];
    }
}

class GFG {
    // Inserts a word into the trie and updates
    // the prefix count at each visited node.
    static void insert(TrieNode root, String word)
    {
        TrieNode node = root;

        for (char ch : word.toCharArray()) {
            int idx = ch - 'a';

            // Create a new node if the path does not exist.
            if (node.child[idx] == null) {
                node.child[idx] = new TrieNode();
            }

            node = node.child[idx];

            // Increment the count of words passing
            // through this prefix node.
            node.cnt++;
        }
    }

    // Returns the number of words that start
    // with the given prefix.
    static int countPref(TrieNode root, String pref)
    {
        TrieNode node = root;

        for (char ch : pref.toCharArray()) {
            int idx = ch - 'a';

            // Prefix not present in the trie.
            if (node.child[idx] == null) {
                return 0;
            }

            node = node.child[idx];
        }

        // The stored count equals the number of
        // words having this prefix.
        return node.cnt;
    }

    static ArrayList<Integer> prefCount(ArrayList<String> s,
                                        ArrayList<String> q)
    {
        // Create the root of the trie.
        TrieNode root = new TrieNode();

        // Insert all words into the trie.
        for (String word : s) {
            insert(root, word);
        }

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

        // Answer each query independently.
        for (String pref : q) {
            res.add(countPref(root, pref));
        }

        return res;
    }

    // Driver code
    public static void main(String[] args)
    {
        ArrayList<String> s = new ArrayList<>(Arrays.asList(
            "abracadabra", "geeksforgeeks", "abracadabra",
            "geeks", "geeksthrill"));

        ArrayList<String> q = new ArrayList<>(
            Arrays.asList("abr", "geeks", "ge", "gar"));

        ArrayList<Integer> res = prefCount(s, q);

        System.out.print("[");

        for (int i = 0; i < res.size(); i++) {
            System.out.print(res.get(i));

            if (i != res.size() - 1) {
                System.out.print(", ");
            }
        }

        System.out.print("]");
    }
}
Python
# Trie node representing a single character.
class TrieNode:

    def __init__(self):
        # Number of words having the prefix represented
        # by the path from root to this node.
        self.cnt = 0

        # Pointers to child nodes for characters 'a' to 'z'.
        self.child = [None] * 26


# Inserts a word into the trie and updates
# the prefix count at each visited node.
def insert(root, word):
    node = root

    for ch in word:
        idx = ord(ch) - ord('a')

        # Create a new node if the path does not exist.
        if node.child[idx] is None:
            node.child[idx] = TrieNode()

        node = node.child[idx]

        # Increment the count of words passing
        # through this prefix node.
        node.cnt += 1


# Returns the number of words that start
# with the given prefix.
def countPref(root, pref):
    node = root

    for ch in pref:
        idx = ord(ch) - ord('a')

        # Prefix not present in the trie.
        if node.child[idx] is None:
            return 0

        node = node.child[idx]

    # The stored count equals the number of
    # words having this prefix.
    return node.cnt


def prefCount(s, q):

    # Create the root of the trie.
    root = TrieNode()

    # Insert all words into the trie.
    for word in s:
        insert(root, word)

    res = []

    # Answer each query independently.
    for pref in q:
        res.append(countPref(root, pref))

    return res


# Driver code
if __name__ == "__main__":
    s = ["abracadabra", "geeksforgeeks", "abracadabra",
         "geeks", "geeksthrill"]

    q = ["abr", "geeks", "ge", "gar"]

    res = prefCount(s, q)

    print("[", end="")

    for i in range(len(res)):
        print(res[i], end="")

        if i != len(res) - 1:
            print(", ", end="")

    print("]", end="")
C#
using System;
using System.Collections.Generic;

// Trie node representing a single character.
class TrieNode {
    // Number of words having the prefix represented
    // by the path from root to this node.
    public int cnt;

    // Pointers to child nodes for characters 'a' to 'z'.
    public TrieNode[] child;

    public TrieNode()
    {
        cnt = 0;
        child = new TrieNode[26];
    }
}

class GFG {
    // Inserts a word into the trie and updates
    // the prefix count at each visited node.
    static void insert(TrieNode root, string word)
    {
        TrieNode node = root;

        foreach(char ch in word)
        {
            int idx = ch - 'a';

            // Create a new node if the path does not exist.
            if (node.child[idx] == null) {
                node.child[idx] = new TrieNode();
            }

            node = node.child[idx];

            // Increment the count of words passing
            // through this prefix node.
            node.cnt++;
        }
    }

    // Returns the number of words that start
    // with the given prefix.
    static int countPref(TrieNode root, string pref)
    {
        TrieNode node = root;

        foreach(char ch in pref)
        {
            int idx = ch - 'a';

            // Prefix not present in the trie.
            if (node.child[idx] == null) {
                return 0;
            }

            node = node.child[idx];
        }

        // The stored count equals the number of
        // words having this prefix.
        return node.cnt;
    }

    static List<int> prefCount(List<string> s,
                               List<string> q)
    {
        // Create the root of the trie.
        TrieNode root = new TrieNode();

        // Insert all words into the trie.
        foreach(string word in s) { insert(root, word); }

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

        // Answer each query independently.
        foreach(string pref in q)
        {
            res.Add(countPref(root, pref));
        }

        return res;
    }

    // Driver code
    static void Main()
    {
        List<string> s = new List<string>{
            "abracadabra", "geeksforgeeks", "abracadabra",
            "geeks", "geeksthrill"
        };

        List<string> q = new List<string>{ "abr", "geeks",
                                           "ge", "gar" };

        List<int> res = prefCount(s, q);

        Console.Write("[");

        for (int i = 0; i < res.Count; i++) {
            Console.Write(res[i]);

            if (i != res.Count - 1) {
                Console.Write(", ");
            }
        }

        Console.Write("]");
    }
}
JavaScript
// Trie node representing a single character.
class TrieNode {
    constructor()
    {
        // Number of words having the prefix represented
        // by the path from root to this node.
        this.cnt = 0;

        // Pointers to child nodes for characters 'a' to
        // 'z'.
        this.child = new Array(26).fill(null);
    }
}

// Inserts a word into the trie and updates
// the prefix count at each visited node.
function insert(root, word)
{
    let node = root;

    for (let ch of word) {
        let idx = ch.charCodeAt(0) - "a".charCodeAt(0);

        // Create a new node if the path does not exist.
        if (node.child[idx] === null) {
            node.child[idx] = new TrieNode();
        }

        node = node.child[idx];

        // Increment the count of words passing
        // through this prefix node.
        node.cnt++;
    }
}

// Returns the number of words that start
// with the given prefix.
function countPref(root, pref)
{
    let node = root;

    for (let ch of pref) {
        let idx = ch.charCodeAt(0) - "a".charCodeAt(0);

        // Prefix not present in the trie.
        if (node.child[idx] === null) {
            return 0;
        }

        node = node.child[idx];
    }

    // The stored count equals the number of
    // words having this prefix.
    return node.cnt;
}

function prefCount(s, q)
{
    // Create the root of the trie.
    let root = new TrieNode();

    // Insert all words into the trie.
    for (let word of s) {
        insert(root, word);
    }

    let res = [];

    // Answer each query independently.
    for (let pref of q) {
        res.push(countPref(root, pref));
    }

    return res;
}

// Driver code
let s = [
    "abracadabra", "geeksforgeeks", "abracadabra", "geeks",
    "geeksthrill"
];

let q = [ "abr", "geeks", "ge", "gar" ];

let res = prefCount(s, q);

process.stdout.write("[");

for (let i = 0; i < res.length; i++) {
    process.stdout.write(res[i].toString());

    if (i !== res.length - 1) {
        process.stdout.write(", ");
    }
}

process.stdout.write("]");

Output
[2, 3, 3, 0]
Comment