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“, “padfla” are 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
- Check if the node for the current character exists in trie
Below is the implementation of the above approach.
// 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 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 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# 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 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.
|
2
Time Complexity: O(N * K), where N is the length of the given string array.
Auxiliary Space: O(N * K)