Count k length prefix matches

Last Updated : 2 May, 2026

Given an array of strings arr[] and some queries where each query consists of a string str and an integer k. The task is to find the count of strings in arr[] whose prefix of length k matches with the k length prefix of str.
Examples: 

Input: arr[] = ["abba", "abbb", "abbc", "abbd", "abaa", "abca"], str = "abbg", k = 3 
Output:
"abba", "abbb", "abbc" and "abbd" are the matching strings.

Input: arr[] = ["geeks", "geeksforgeeks", "forgeeks"], str = "geeks", k = 2 
Output:

Try It Yourself
redirect icon

[Naive Approach] Using Direct Prefix Comparison - O(n * k) Time and O(1) Space

We compare the first k characters of the given string with the first k characters of every string in the array. If they match, we count that string.

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


int PrefixMatchCount(vector<string>& arr, string str, int k) {

    // If input string is smaller than k, no match possible
    if (str.length() < k)
        return 0;
        
    // Initialize count of matching strings
    int count = 0; 

    // Iterate through each string in the vector
    for (const string& s : arr) {

        // Skip strings smaller than k
        if (s.length() < k)
            continue;

        // Compare first k characters
        if (s.substr(0, k) == str.substr(0, k)) {
            
            // Increment if match found
            count++;
            
        }
    }

    // Return final count
    return count; 
}

int main() {
    vector<string> arr = { "abba", "abbb", "abbc", "abbd", "abaa", "abca" };
    string str = "abbg";
    int k = 3;

    cout << PrefixMatchCount(arr, str, k) << endl;

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

class GFG {

    static int PrefixMatchCount(String[] arr, String str, int k) {

        // If input string is smaller than k, no match possible
        if (str.length() < k)
            return 0;

        // Initialize count of matching strings
        int count = 0;

        // Iterate through each string in the array
        for (String s : arr) {

            // Skip strings smaller than k
            if (s.length() < k)
                continue;

            // Compare first k characters
            if (s.substring(0, k).equals(str.substring(0, k))) {

                // Increment if match found
                count++;

            }
        }

        // Return final count
        return count;
    }

    public static void main(String[] args) {
        String[] arr = {
            "abba", "abbb", "abbc", "abbd", "abaa", "abca"
        };
        String str = "abbg";
        int k = 3;

        System.out.println(PrefixMatchCount(arr, str, k));
    }
}
Python
def PrefixMatchCount(arr, string, k):

    # If input string is smaller than k, no match possible
    if len(string) < k:
        return 0

    # Initialize count of matching strings
    count = 0

    # Iterate through each string in the vector
    for s in arr:

        # Skip strings smaller than k
        if len(s) < k:
            continue

        # Compare first k characters
        if s[:k] == string[:k]:

            # Increment if match found
            count += 1

    # Return final count
    return count


arr = ["abba", "abbb", "abbc", "abbd", "abaa", "abca"]
string = "abbg"
k = 3

print(PrefixMatchCount(arr, string, k))
C#
using System;
using System.Collections.Generic;

class GFG {

    static int PrefixMatchCount(List<string> arr, string str, int k) {

        // If input string is smaller than k, no match possible
        if (str.Length < k)
            return 0;

        // Initialize count of matching strings
        int count = 0;

        // Iterate through each string in the vector
        foreach (string s in arr) {

            // Skip strings smaller than k
            if (s.Length < k)
                continue;

            // Compare first k characters
            if (s.Substring(0, k).Equals(str.Substring(0, k))) {

                // Increment if match found
                count++;

            }
        }

        // Return final count
        return count;
    }

    static void Main() {
        List<string> arr = new List<string> {
            "abba", "abbb", "abbc", "abbd", "abaa", "abca"
        };

        string str = "abbg";
        int k = 3;

        Console.WriteLine(PrefixMatchCount(arr, str, k));
    }
}
JavaScript
function PrefixMatchCount(arr, str, k) {

    // If input string is smaller than k → no match possible
    if (str.length < k)
        return 0;

    // Initialize count of matching strings
    let count = 0;

    // Iterate through each string in the vector
    for (let s of arr) {

        // Skip strings smaller than k
        if (s.length < k)
            continue;

        // Compare first k characters
        if (s.substring(0, k) === str.substring(0, k)) {

            // Increment if match found
            count++;

        }
    }

    // Return final count
    return count;
}

// Driver code
let arr = ["abba", "abbb", "abbc", "abbd", "abaa", "abca"];
let str = "abbg";
let k = 3;

console.log(PrefixMatchCount(arr, str, k));

Output
4

[Optimal Approach] Using Trie (Prefix Counting) - O(n * L + k) Time and O(n * L) Space

We use a Trie to store all strings and maintain frequency at each node. While inserting, we increment the frequency for every prefix. Then for a given string, we traverse up to length k and return the frequency stored at that node, which represents how many strings share that prefix.

  • Create a Trie node structure with 26 children and frequency
  • Insert all strings into the Trie. While inserting, increment frequency at each node
  • Start traversing the given string from root, move character by character in Trie. If path breaks, return 0
  • When length k is reached, return stored frequency
C++
#include <iostream>
#include <vector>
#include <string>
using namespace std;

// Trie node (considering only lowercase alphabets)
struct TrieNode {
    TrieNode* arr[26];
    int freq;

    // Constructor to initialize node
    TrieNode() {
        freq = 0;
        for (int i = 0; i < 26; i++)
            arr[i] = nullptr;
    }
};

// Function to insert a node in the trie
TrieNode* insert(string s, TrieNode* root)
{
    int in;
    TrieNode* cur = root;

    for (int i = 0; i < s.length(); i++) {
        in = s[i] - 'a';

        // If there is no node created then create one
        if (cur->arr[in] == nullptr)
            cur->arr[in] = new TrieNode();

        // Increase the frequency of the node
        cur->arr[in]->freq++;

        // Move to the next node
        cur = cur->arr[in];
    }

    // Return the updated root
    return root;
}

// Function to return the count of strings
// whose prefix of length k matches with the
// k length prefix of the given string
int kLengthPref(vector<string> arr, int k, string str)
{
    // Create root of trie
    TrieNode* root = new TrieNode();

    // Insert all strings into trie
    for (int i = 0; i < arr.size(); i++)
        root = insert(arr[i], root);

    int in, count = 0;
    TrieNode* cur = root;

    // Traverse the string
    for (int i = 0; i < str.length(); i++) {
        in = str[i] - 'a';

        // If there is no node then return 0
        if (cur->arr[in] == nullptr)
            return 0;

        // Else traverse to the required node
        cur = cur->arr[in];

        count++;

        // Return the required count
        if (count == k)
            return cur->freq;
    }

    return 0;
}

// Driver code
int main()
{
    vector<string> arr = { "abba", "abbb", "abbc", "abbd", "abaa", "abca" };

    // Query 1
    cout << kLengthPref(arr, 3, "abbg") << endl;

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

// Trie node (considering only lowercase alphabets)
class TrieNode {
    TrieNode[] arr = new TrieNode[26];
    int freq;

    // Constructor to initialize node
    TrieNode() {
        freq = 0;
        for (int i = 0; i < 26; i++)
            arr[i] = null;
    }
}

class GFG {

    // Function to insert a node in the trie
    static TrieNode insert(String s, TrieNode root)
    {
        int in;
        TrieNode cur = root;

        for (int i = 0; i < s.length(); i++) {
            in = s.charAt(i) - 'a';

            // If there is no node created then create one
            if (cur.arr[in] == null)
                cur.arr[in] = new TrieNode();

            // Increase the frequency of the node
            cur.arr[in].freq++;

            // Move to the next node
            cur = cur.arr[in];
        }

        // Return the updated root
        return root;
    }

    // Function to return the count of strings
    // whose prefix of length k matches with the
    // k length prefix of the given string
    static int kLengthPref(String[] arr, int k, String str)
    {
        // Create root of trie
        TrieNode root = new TrieNode();

        // Insert all strings into trie
        for (int i = 0; i < arr.length; i++)
            root = insert(arr[i], root);

        int in, count = 0;
        TrieNode cur = root;

        // Traverse the string
        for (int i = 0; i < str.length(); i++) {
            in = str.charAt(i) - 'a';

            // If there is no node then return 0
            if (cur.arr[in] == null)
                return 0;

            // Else traverse to the required node
            cur = cur.arr[in];

            count++;

            // Return the required count
            if (count == k)
                return cur.freq;
        }

        return 0;
    }

    // Driver code
    public static void main(String[] args)
    {
        String[] arr = {
            "abba", "abbb", "abbc", "abbd", "abaa", "abca"
        };

        // Query 1
        System.out.println(kLengthPref(arr, 3, "abbg"));
    }
}
Python
# Trie node (considering only lowercase alphabets)
class TrieNode:
    # Constructor to initialize node
    def __init__(self):
        self.arr = [None] * 26
        self.freq = 0


# Function to insert a node in the trie
def insert(s, root):

    cur = root

    for i in range(len(s)):
        idx = ord(s[i]) - ord('a')

        # If there is no node created then create one
        if cur.arr[idx] is None:
            cur.arr[idx] = TrieNode()

        # Increase the frequency of the node
        cur.arr[idx].freq += 1

        # Move to the next node
        cur = cur.arr[idx]

    # Return the updated root
    return root


# Function to return the count of strings
# whose prefix of length k matches with the
# k length prefix of the given string
def kLengthPref(arr, k, string):

    # Create root of trie
    root = TrieNode()

    # Insert all strings into trie
    for i in range(len(arr)):
        root = insert(arr[i], root)

    count = 0
    cur = root

    # Traverse the string
    for i in range(len(string)):
        idx = ord(string[i]) - ord('a')

        # If there is no node then return 0
        if cur.arr[idx] is None:
            return 0

        # Else traverse to the required node
        cur = cur.arr[idx]

        count += 1

        # Return the required count
        if count == k:
            return cur.freq

    return 0


# Driver code
arr = ["abba", "abbb", "abbc", "abbd", "abaa", "abca"]

# Query 1
print(kLengthPref(arr, 3, "abbg"))
C#
using System;
using System.Collections.Generic;

// Trie node (considering only lowercase alphabets)
class TrieNode {
    public TrieNode[] arr = new TrieNode[26];
    public int freq;

    // Constructor to initialize node
    public TrieNode() {
        freq = 0;
        for (int i = 0; i < 26; i++)
            arr[i] = null;
    }
}

class GFG {

    // Function to insert a node in the trie
    static TrieNode insert(string s, TrieNode root)
    {
        int inx;
        TrieNode cur = root;

        for (int i = 0; i < s.Length; i++) {
            inx = s[i] - 'a';

            // If there is no node created then create one
            if (cur.arr[inx] == null)
                cur.arr[inx] = new TrieNode();

            // Increase the frequency of the node
            cur.arr[inx].freq++;

            // Move to the next node
            cur = cur.arr[inx];
        }

        // Return the updated root
        return root;
    }

    // Function to return the count of strings
    // whose prefix of length k matches with the
    // k length prefix of the given string
    static int kLengthPref(List<string> arr, int k, string str)
    {
        // Create root of trie
        TrieNode root = new TrieNode();

        // Insert all strings into trie
        for (int i = 0; i < arr.Count; i++)
            root = insert(arr[i], root);

        int inx, count = 0;
        TrieNode cur = root;

        // Traverse the string
        for (int i = 0; i < str.Length; i++) {
            inx = str[i] - 'a';

            // If there is no node then return 0
            if (cur.arr[inx] == null)
                return 0;

            // Else traverse to the required node
            cur = cur.arr[inx];

            count++;

            // Return the required count
            if (count == k)
                return cur.freq;
        }

        return 0;
    }

    // Driver code
    static void Main()
    {
        List<string> arr = new List<string> {
            "abba", "abbb", "abbc", "abbd", "abaa", "abca"
        };

        // Query 1
        Console.WriteLine(kLengthPref(arr, 3, "abbg"));
    }
}
JavaScript
// Trie node (considering only lowercase alphabets)
class TrieNode {
    // Constructor to initialize node
    constructor() {
        this.arr = new Array(26).fill(null);
        this.freq = 0;
    }
}

// Function to insert a node in the trie
function insert(s, root)
{
    let cur = root;

    for (let i = 0; i < s.length; i++) {
        let idx = s.charCodeAt(i) - 'a'.charCodeAt(0);

        // If there is no node created then create one
        if (cur.arr[idx] === null)
            cur.arr[idx] = new TrieNode();

        // Increase the frequency of the node
        cur.arr[idx].freq++;

        // Move to the next node
        cur = cur.arr[idx];
    }

    // Return the updated root
    return root;
}

// Function to return the count of strings
// whose prefix of length k matches with the
// k length prefix of the given string
function kLengthPref(arr, k, str)
{
    // Create root of trie
    let root = new TrieNode();

    // Insert all strings into trie
    for (let i = 0; i < arr.length; i++)
        root = insert(arr[i], root);

    let count = 0;
    let cur = root;

    // Traverse the string
    for (let i = 0; i < str.length; i++) {
        let idx = str.charCodeAt(i) - 'a'.charCodeAt(0);

        // If there is no node then return 0
        if (cur.arr[idx] === null)
            return 0;

        // Else traverse to the required node
        cur = cur.arr[idx];

        count++;

        // Return the required count
        if (count === k)
            return cur.freq;
    }

    return 0;
}

// Driver code
let arr = ["abba", "abbb", "abbc", "abbd", "abaa", "abca"];

// Query 1
console.log(kLengthPref(arr, 3, "abbg"));

Output
4


Comment