Solution Review: Prefix Map

See the solution to the prefix map problem challenge.

Solution

#include <iostream>
#include <vector>
#include <unordered_map>
#include <string>
using namespace std;
// Definition of TrieNode
class TrieNode
{
public:
// An integer to store the total value associated with every node and it's children
int val;
// children array store pointer to TrieNode of next 26 alphabets
TrieNode *children[26];
};
class Trie
{
public:
// intialize a hashmap
unordered_map<string, int> keyToValMap;
// intialize the trie root
TrieNode * root;
Trie()
{
root = new TrieNode();
}
// function to insert key value data in the trie
bool insert(string key, int diff)
{
// point the current node to the root
TrieNode *curr = root;
// intialize an integer value to count insertions in the trie
int insertions = 0;
// iterate through the letters of the key
for (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 node
curr = curr->children[c];
// add the diff value to the node's original value
curr->val += diff;
}
// if insertion count is greater than zero
// means the key did not previously exist, true is returned
return insertions > 0;
}
int search(string word)
{
TrieNode *curr = root;
//traverse the trie starting from the root
for (char c: word)
{
c -= 'a';
// if there is no node for a query letter in trie
// return false and terminate the search
if (curr->children[c] == nullptr)
{
return 0;
}
curr = curr->children[c];
}
// return the val associated with the last node of query string
return curr->val;
}
};
class PrefixMap
{
public:
// initialize a trie
Trie *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 hashmap
int updateDiff = val - oldVal;
return trie->insert(key, updateDiff);
}
int getSum(string prefixKey)
{
return trie->search(prefixKey);
}
};
Solution for prefix map problem challenge in C++

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 named keyToValMap, 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

  1. Update the value of the key string in the keyToValMap hashmap.

  2. 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.

  3. 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

  1. Traverse the trie to search for the prefix query string.

  2. 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 = NN ...

Access this course and 1400+ top-rated courses and projects.