Solution Review: Insertion Count
See the solution to the problem challenge.
We'll cover the following...
Solution
#include <iostream>#include <vector>#include <algorithm>using namespace std;// Definition of a trie nodeclass TrieNode{public:// children array store pointer to TrieNode of next 52 alphabets (26 upper + 26 lower)TrieNode *children[52];// A flag used to identify if a node denotes last character of a patternbool isEndOfPattern;};class Trie{TrieNode * root;public:Trie(){root = new TrieNode();}// inserts the pattern into the trievoid insert(string pattern){// point the current node to rootTrieNode *curr = root;// iterate all letters in the patternfor (auto ch: pattern){int idx = -1;// if character is upper case// calculate its index//[A....Z] map to indexes[26...51]if (ch >= 'A' && ch <= 'Z')idx = 26 + ch - 'A';elseidx = ch - 'a';if (curr->children[idx] == NULL)curr->children[idx] = new TrieNode();curr = curr->children[idx];}// mark isEndOfPattern as "true"// for the last nodecurr->isEndOfPattern = true;}int countInsertions(string word){// point the current node to rootTrieNode *curr = root;// initialize a counter for calculating insertionsint insertions = 0;// iterate all letters in the wordfor (auto ch: word){int idx = -1;// if character is upper case// it should be necessarily presentif (ch >= 'A' && ch <= 'Z'){idx = 26 + ch - 'A';// if child node not found in trie, return -1// if found, the move to the child nodeif (curr->children[idx] == NULL)return -1;curr = curr->children[idx];}else{idx = ch - 'a';// if character is lower case// if found, the move to the child node// else if not found, increment the insertion counterif (curr->children[idx] != NULL)curr = curr->children[idx];elseinsertions++;}}// return the value of isEndOfPattern// associated with the last node of the word// value is "true" if pattern is completely matchedif (!curr->isEndOfPattern)return -1;return insertions;}};vector<int> countPatternInsertions(vector<string> &words, string pattern){// Intialize a trieTrie *trie = new Trie();// insert the pattern into the trietrie->insert(pattern);vector<int> answer;// For all words, check if they match the patternfor (int i = 0; i < words.size(); i++){answer.push_back(trie->countInsertions(words[i]));}return answer;}
Intuition
This problem is an extension of pattern matching. Let's discuss the critical observations. First, the uppercase letters must be in the same order in the pattern as they appear in the word. The lowercase letters might or might not be part of the pattern. This problem deals with pattern matching in strings. As discussed in the introduction, tries can be an ideal candidate for solving this.
There are both uppercase and lowercase letters; therefore, an array of size 52
is used to store the child trie nodes. We store lowercase letters in the first 26 indexes and uppercase letters in the last 26 indexes. We will also include a boolean parameter, isEndOfPattern
, to mark the ending of the pattern string in the trie.
// Definition of a trie nodeclass TrieNode{public:// children array store pointer to TrieNode of// next 52 alphabets (26 upper + 26 lower)TrieNode* children[52];// A flag used to identify if a node denotes// last character of a patternbool isEndOfPattern;};
Algorithm
We initialize a variable insertions = 0
. This will keep the count of the total number of inserts to match the pattern. Then, for each word in the input, we iterate through the trie with characters in the word to check whether it matches the pattern. The procedure for handling uppercase and lowercase letters will be different here.
Case 1: Uppercase letters
If the character is an uppercase letter, check whether there exists a path with that character from the current trie node, which means that the trie node children array representing this letter is not null
.
If the path does not exist, the letter is not present in the trie; therefore, the word does not match the pattern, and we can return -1
. Otherwise, traverse down the node and move to the subsequent letter in the given word if a path exists.
Case 2: Lowercase letters
If the letter is lowercase, it's not necessarily present in the pattern. First, check whether the index in the trie node children array representing this letter is null
. If it's not null
, update the current trie node with the next trie node; otherwise, increment the insertions
variable.
Following the above procedure, once the word is finished and we encounter a trie node with isEndOfPattern
equal to true
, we can conclude that the word matches the pattern and we can return the insertions counter. ...