LeetCode //C - 677. Map Sum Pairs
【代码】LeetCode //C - 677. Map Sum Pairs。
677. Map Sum Pairs
Design a map that allows you to do the following:
- Maps a string key to a given value.
- Returns the sum of the values that have a key with a prefix equal to a given string.
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
- At most 50 calls will be made to insert and sum.
From: LeetCode
Link: 677. Map Sum Pairs
Solution:
Ideas:
-
Trie Node value holds the sum of values of all keys passing through that node.
-
A separate hashmap is used to track the current value of keys and to calculate the delta when updating an existing key.
-
The sum operation just walks down the Trie using the prefix and returns the stored value.
Code:
#define ALPHABET_SIZE 26
#define MAX_KEY_LEN 51
#define HASH_MAP_SIZE 1000
typedef struct TrieNode {
int value;
struct TrieNode* children[ALPHABET_SIZE];
} TrieNode;
typedef struct KeyValue {
char key[MAX_KEY_LEN];
int val;
struct KeyValue* next;
} KeyValue;
typedef struct {
TrieNode* root;
KeyValue* hashMap[HASH_MAP_SIZE];
} MapSum;
// Hash function for key
unsigned int hash(char* key) {
unsigned int hash = 5381;
while (*key)
hash = ((hash << 5) + hash) + *key++;
return hash % HASH_MAP_SIZE;
}
KeyValue* findKeyValue(KeyValue* head, const char* key) {
while (head) {
if (strcmp(head->key, key) == 0)
return head;
head = head->next;
}
return NULL;
}
TrieNode* createTrieNode() {
TrieNode* node = (TrieNode*)calloc(1, sizeof(TrieNode));
return node;
}
MapSum* mapSumCreate() {
MapSum* obj = (MapSum*)malloc(sizeof(MapSum));
obj->root = createTrieNode();
for (int i = 0; i < HASH_MAP_SIZE; ++i)
obj->hashMap[i] = NULL;
return obj;
}
void insertToTrie(TrieNode* root, const char* key, int delta) {
TrieNode* node = root;
while (*key) {
int index = *key - 'a';
if (!node->children[index])
node->children[index] = createTrieNode();
node = node->children[index];
node->value += delta;
key++;
}
}
void mapSumInsert(MapSum* obj, char* key, int val) {
unsigned int h = hash(key);
KeyValue* entry = findKeyValue(obj->hashMap[h], key);
int oldVal = 0;
if (entry) {
oldVal = entry->val;
entry->val = val;
} else {
entry = (KeyValue*)malloc(sizeof(KeyValue));
strcpy(entry->key, key);
entry->val = val;
entry->next = obj->hashMap[h];
obj->hashMap[h] = entry;
}
insertToTrie(obj->root, key, val - oldVal);
}
int mapSumSum(MapSum* obj, char* prefix) {
TrieNode* node = obj->root;
while (*prefix) {
int index = *prefix - 'a';
if (!node->children[index])
return 0;
node = node->children[index];
prefix++;
}
return node->value;
}
void freeTrie(TrieNode* node) {
if (!node) return;
for (int i = 0; i < ALPHABET_SIZE; ++i)
freeTrie(node->children[i]);
free(node);
}
void freeHashMap(KeyValue* head) {
while (head) {
KeyValue* temp = head;
head = head->next;
free(temp);
}
}
void mapSumFree(MapSum* obj) {
freeTrie(obj->root);
for (int i = 0; i < HASH_MAP_SIZE; ++i)
freeHashMap(obj->hashMap[i]);
free(obj);
}
更多推荐
所有评论(0)