Solution Review: Prefix Map
See the solution to the prefix map problem challenge.
We'll cover the following...
Solution
#include <iostream>#include <vector>#include <unordered_map>#include <string>using namespace std;// Definition of TrieNodeclass TrieNode{public:// An integer to store the total value associated with every node and it's childrenint val;// children array store pointer to TrieNode of next 26 alphabetsTrieNode *children[26];};class Trie{public:// intialize a hashmapunordered_map<string, int> keyToValMap;// intialize the trie rootTrieNode * root;Trie(){root = new TrieNode();}// function to insert key value data in the triebool insert(string key, int diff){// point the current node to the rootTrieNode *curr = root;// intialize an integer value to count insertions in the trieint insertions = 0;// iterate through the letters of the keyfor (int i = 0; i < key.size(); i++){int c = key[i] - 'a';if (curr->children[c] == nullptr){curr->children[c] = new TrieNode();insertions++;}// move to the child nodecurr = curr->children[c];// add the diff value to the node's original valuecurr->val += diff;}// if insertion count is greater than zero// means the key did not previously exist, true is returnedreturn insertions > 0;}int search(string word){TrieNode *curr = root;//traverse the trie starting from the rootfor (char c: word){c -= 'a';// if there is no node for a query letter in trie// return false and terminate the searchif (curr->children[c] == nullptr){return 0;}curr = curr->children[c];}// return the val associated with the last node of query stringreturn curr->val;}};class PrefixMap{public:// initialize a trieTrie *trie = new Trie();bool putInMap(string key, int val){int oldVal = trie->keyToValMap[key];trie->keyToValMap[key] = val;// calculate the value difference// before updating in the hashmapint updateDiff = val - oldVal;return trie->insert(key, updateDiff);}int getSum(string prefixKey){return trie->search(prefixKey);}};
Intuition
We can use an approach similar to the prefix count problem, where we add all the key strings and associated values into a trie.
The problem requires implementing the following methods:
putInMap
: The function takes a key string and an integer value as input and maps a string key to a given integer value. It returns true if the key did not exist in the map previously; else, it returns false. This can be easily achieved by using a hashmap. We use a hashmap namedkeyToValMap
, which maps the string key to its value.getSum
: The function takes a prefix string as input and returns the sum of the integer values of all the keys that have the query as a prefix. Essentially, we need to return the sum of the values of all the string keys that have the given query string as a prefix.
A trie can be helpful here since we need to perform prefix search-related operations. We introduce a new integer parameter val
in the definition of the trie node. This integer will store the sum of the values associated with all the child nodes of the current node. When we receive a query string, we traverse the trie to find it and return the val
associated with the last trie node of the query string.
Algorithm
putInMap
Update the value of the key string in the
keyToValMap
hashmap.Get the previous value associated with the key, if any. Next, calculate the difference between the old value associated with the key and the new value inserted in the hashmap. This
diff
will be used while inserting the key string in the trie.Insert the key string in the trie with the new value. If while inserting a query string in the trie we encounter a scenario where the node does not exist, we'll create the child node. For each node in the path from the root to the last node of the query string, keep adding the
diff
value to the node's original value.
getSum
Traverse the trie to search for the prefix query string.
If the string does not exist in the trie, return
0
. If it exists, return the value associated with the trie node of the last character of the prefix string.
Visualization
Let's see an example to understand this better. For key strings flip
and flick
, a trie would look like the one given below:
Complexity analysis
Variables
The number of times
putInMap
is called =...