Maximum number of Strings with Common Prefix of length K
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++
// 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. |
2
Time Complexity: O(N * K), where N is the length of the given string array.
Auxiliary Space: O(N * K)
Please Login to comment...