Design a map that allows you to do the following:
Implement the MapSum
class:
MapSum()
Initializes the MapSum
object.void insert(String key, int val)
Inserts the key-val
pair into the map. If the key
already existed, the original key-value
pair will be overridden to the new one.int sum(string prefix)
Returns the sum of all the pairs' value whose key
starts with the prefix
.Example 1:
Input ["MapSum", "insert", "sum", "insert", "sum"] [[], ["apple", 3], ["ap"], ["app", 2], ["ap"]] Output [null, null, 3, null, 5] Explanation MapSum mapSum = new MapSum(); mapSum.insert("apple", 3); mapSum.sum("ap"); // return 3 (apple = 3) mapSum.insert("app", 2); mapSum.sum("ap"); // return 5 (apple + app = 3 + 2 = 5)
Constraints:
1 <= key.length, prefix.length <= 50
key
and prefix
consist of only lowercase English letters.1 <= val <= 1000
50
calls will be made to insert
and sum
.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method for the map sum problem means we will recalculate the sum for a given prefix every time. It involves going through all the previously stored words to find matches for the provided prefix and add their corresponding values.
Here's how the algorithm would work step-by-step:
class MapSum:
def __init__(self):
self.word_value_map = {}
def insert(self, key, value):
self.word_value_map[key] = value
def sum(self, prefix):
total_sum = 0
# Iterate through each word in our storage to check for matches
for word, value in self.word_value_map.items():
# See if the current word starts with the given prefix
if word.startswith(prefix):
# Add the word's value to the running total if it matches
total_sum += value
return total_sum
The problem requires us to store word-value pairs and calculate sums based on prefixes. Instead of recomputing sums every time, we can use a data structure that allows us to efficiently update and retrieve information about prefixes.
Here's how the algorithm would work step-by-step:
class MapSum:
def __init__(self):
self.word_values = {}
self.prefix_sums = {}
def insert(self, word: str, value: int) -> None:
original_value = self.word_values.get(word, 0)
value_difference = value - original_value
self.word_values[word] = value
# Iterate over all prefixes of the word.
for i in range(1, len(word) + 1):
prefix = word[:i]
# Update prefix sums, adding the value difference.
if prefix in self.prefix_sums:
self.prefix_sums[prefix] += value_difference
else:
self.prefix_sums[prefix] = value_difference
def sum(self, prefix: str) -> int:
# Return the stored sum for the given prefix.
return self.prefix_sums.get(prefix, 0)
# Your MapSum object will be instantiated and called as such:
# mapSum = MapSum()
# mapSum.insert("apple", 3)
# mapSum.sum("ap")
# mapSum.insert("app", 2)
# mapSum.sum("ap")
Case | How to Handle |
---|---|
Empty key | Empty key should be allowed and treated as a valid, potentially meaningful prefix. |
Null input for key | Throw an IllegalArgumentException or return a specific error code, as null keys are generally disallowed. |
Very long key string (close to max string length) | Ensure solution does not cause StackOverflowError or excessive memory allocation during string operations or trie traversal. |
Large number of inserts with the same key overwriting the value | Overwriting existing keys should work correctly, and the sum should reflect the last inserted value. |
Large number of keys with common prefixes, stressing trie memory usage | The solution's memory usage should scale reasonably, ideally linearly, with the number of distinct prefixes rather than the total length of all keys. |
Integer overflow when calculating the sum of values | Use a data type with a larger range (e.g., long) for storing sums to prevent integer overflow. |
Non-ASCII characters in the key string | The Trie implementation needs to handle Unicode characters correctly (consider using a wider character type or appropriate encoding). |
Prefix that does not exist in the map | The sum operation should return 0 when the prefix does not exist in the map. |