Open In App

Maximum number of Strings with Common Prefix of length K

Improve
Improve
Like Article
Like
Save
Share
Report

Given a string array arr[] of length N, the task is to find the maximum number of strings that share a common prefix of length K.

Examples:

Input: arr = { { “hello”, “heydeei”, “hap”, “hak”, “paloa”, “padfk”, “padfla”, “pada” } }, K = 4
Output: 2
Explanation: String padfk“, “padflaare the two string that share the common prefix of length k.

Input: arr = { { “happy”, “hapi”, “hape”, “hak”, “paloa”, “padfk”, “padfla”, “pada” } }, K = 3
Output: 3

An approach using Trie:

The idea is to use Trie data structure to keep a count of all occurrences of a prefix by maintaining a variable count in the structure of the node of Trie. While inserting a new string into trie keep checking K character of new strings are inserted or not. If we’d already inserted K characters into trie than maximise the count of prefix at that node.

Follow the steps below to implement the above idea:

  • Iterate over the given string array and Insert the given strings into Trie one by one
    • Initialize a trie node curr which points to the root initially
    • Iterate over the length of the given string
      • Check if the node for the current character exists in trie
        • If not exist then create a new trie node and assign the reference to the current node child
      • Increment the count of prefixes.
      • Check if the length of the current string becomes greater than the required K.
        • If true, then update the result with the maximum between the current result or the count of occurrences of the current prefix.
      • Move the current pointer to the next node

Below is the implementation of the above approach.

C++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Structure of a Trie Node
struct Node {
    Node* child[26];
    int count = 0;
};
 
Node* root;
 
int result = 0, K;
 
// Insert given string into Trie
void insert(string& s)
{
 
    // Initialize a Trie Node curr which
    // point to root initially
    Node* curr = root;
 
    // Iterate over the length of
    // given string
    for (int i = 0; i < s.size(); i++) {
 
        // Check if Node for current
        // character exit in Trie If not
        // exist then create new Trie node
        // and assign the reference to
        // current node child
        if (curr->child[s[i] - 'a'] == NULL) {
            curr->child[s[i] - 'a'] = new Node();
        }
 
        // Increment the count of prefix.
        curr->child[s[i] - 'a']->count++;
 
        // Check if length of the current
        // string becomes greater than
        // required k If true, then maximise
        // longest prefix will result
        if (i + 1 == K) {
            result = max(result,
                         curr->child[s[i] - 'a']->count);
            break;
        }
 
        // Move the current pointer
        // to next node
        curr = curr->child[s[i] - 'a'];
    }
}
 
// Driver code
int main()
{
 
    vector<string> arr
        = { { "hello", "heydeei", "hap", "hak", "paloa",
              "padfk", "padfla", "pada" } };
    K = 4;
 
    // Initialize root of Trie Node
    root = new Node();
    for (auto s : arr) {
        insert(s);
    }
 
    cout << result;
    return 0;
}


Java




// Java program to implement
// the above approach
import java.util.*;
 
class GFG
{
 
  // Structure of a Trie Node
  public static class Node {
    Node []child = new Node[26];
    int count = 0;
  };
 
  public static Node root;
 
  public static int result = 0, K;
 
  // Insert given string into Trie
  public static void insert(String s)
  {
 
    // Initialize a Trie Node curr which
    // point to root initially
    Node curr= root;
 
    // Iterate over the length of
    // given string
    for (int i = 0; i < s.length(); i++) {
 
      // Check if Node for current
      // character exit in Trie If not
      // exist then create new Trie node
      // and assign the reference to
      // current node child
      if (curr.child[s.charAt(i) - 'a'] == null) {
        curr.child[s.charAt(i) - 'a'] = new Node();
      }
 
      // Increment the count of prefix.
      curr.child[s.charAt(i) - 'a'].count++;
 
      // Check if length of the current
      // string becomes greater than
      // required k If true, then maximise
      // longest prefix will result
      if (i + 1 == K) {
        result = Math.max(result,curr.child[s.charAt(i) - 'a'].count);
        break;
      }
 
      // Move the current pointer
      // to next node
      curr = curr.child[s.charAt(i) - 'a'];
    }
  }
 
  // Driver code
  public static void main(String[] args)
  {
 
    String[] arr = { "hello", "heydeei", "hap", "hak", "paloa",
                    "padfk", "padfla", "pada" } ;
    K = 4;
 
    // Initialize root of Trie Node
    root = new Node();
    for (String s : arr) {
      insert(s);
    }
 
    System.out.print(result);
  }
}
 
// This code is contributed by Pushpesh Raj.


Python3




# Python3 code to implement the approach
 
# Structure of a Trie Node
class Node:
     
    # Stores index
    # of string
    def __init__(self):
        self.child = [None]*26
        self.count = 0
     
result=0
K=0
root = None
 
# Insert given string into Trie
def insert(s):
    global root
    global result
    global K
     
    # Initialize a Trie Node curr which
    # point to root initially
     
    curr = root
 
    # Iterate over the length of
    # given string
    for i in range(len(s)):
 
        # Check if Node for current
        # character exit in Trie If not
        # exist then create new Trie node
        # and assign the reference to
        # current node child
        if (not curr.child[ord(s[i]) - ord('a')]):
 
            # Create a new node of Trie.
            curr.child[ord(s[i]) - ord('a')] = Node()
         
        # Increment the count of prefix.
        curr.child[ord(s[i]) - ord('a')].count += 1
         
        # Check if length of the current
        # string becomes greater than
        # required k If true, then maximise
        # longest prefix will result
        if(i+1==K):
            result=max(result,curr.child[ord(s[i]) - ord('a')].count)
            break
 
        # Move the current pointer
        # to next node
        curr = curr.child[ord(s[i]) - ord('a')]
         
    return curr
 
 
 
# Driver Code
if __name__ == '__main__':
    arr = ["hello", "heydeei", "hap", "hak", "paloa","padfk", "padfla", "pada"]
    K=4
 
    N = len(arr)
    root=Node()
     
    for i in range(N):
        insert(arr[i])
 
    print(result)
 
# This code is contributed by Aman Kumar


C#




// C# program to implement
// the above approach
using System;
public class GFG {
 
  // Structure of a Trie Node
  class Node {
    public Node[] child = new Node[26];
    public int count = 0;
  };
 
  static Node root;
 
  static int result = 0, K;
 
  // Insert given string into Trie
  static void insert(String s)
  {
 
    // Initialize a Trie Node curr which
    // point to root initially
    Node curr = root;
 
    // Iterate over the length of
    // given string
    for (int i = 0; i < s.Length; i++) {
 
      // Check if Node for current
      // character exit in Trie If not
      // exist then create new Trie node
      // and assign the reference to
      // current node child
      if (curr.child[s[i] - 'a'] == null) {
        curr.child[s[i] - 'a'] = new Node();
      }
 
      // Increment the count of prefix.
      curr.child[s[i] - 'a'].count++;
 
      // Check if length of the current
      // string becomes greater than
      // required k If true, then maximise
      // longest prefix will result
      if (i + 1 == K) {
        result = Math.Max(
          result, curr.child[s[i] - 'a'].count);
        break;
      }
 
      // Move the current pointer
      // to next node
      curr = curr.child[s[i] - 'a'];
    }
  }
 
  // Driver code
  static void Main()
  {
 
    string[] arr
      = { "hello", "heydeei", "hap",    "hak",
         "paloa", "padfk",   "padfla", "pada" };
    K = 4;
 
    // Initialize root of Trie Node
    root = new Node();
    for (int i = 0; i < arr.Length; i++) {
      insert(arr[i]);
    }
 
    Console.Write(result);
  }
}
 
// This code is contributed by garg28harsh.


Javascript




// javascript code to implement the approach
 
// Structure of a Trie Node
class Node {
    constructor(){
    this.child = new Array(26);
    this.count = 0;
    }
}
 
let root;
 
let result = 0, K;
 
// Insert given string into Trie
function insert( s)
{
    // Initialize a Trie Node curr which
    // point to root initially
    let curr = root;
    // Iterate over the length of
    // given string
    for (let i = 0; i < s.length; i++) {
 
        // Check if Node for current
        // character exit in Trie If not
        // exist then create new Trie node
        // and assign the reference to
        // current node child
        let x= s.charCodeAt(i)-97;
        if (curr.child[x] == null) {
            curr.child[x] = new Node();
        }
 
        // Increment the count of prefix.
        curr.child[x].count++;
 
        // Check if length of the current
        // string becomes greater than
        // required k If true, then maximise
        // longest prefix will result
        if (i + 1 == K) {
            result = Math.max(result,
                         curr.child[x].count);
            break;
        }
 
        // Move the current pointer
        // to next node
        curr = curr.child[x];
    }
}
 
// Driver code
 
    let arr = [ "hello", "heydeei", "hap", "hak", "paloa",
              "padfk", "padfla", "pada"];
    K = 4;
 
    // Initialize root of Trie Node
    root = new Node();
    for (let i=0;i<arr.length;i++) {
        let s= arr[i];
        insert(s);
    }
 
    console.log(result);
     
    // This code is contributed by garg28harsh.


Output

2

Time Complexity: O(N * K), where N is the length of the given string array.
Auxiliary Space: O(N * K)



Last Updated : 21 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads