一、题目

【LeetCode677】键值映射_前缀树


提示:

  • 1 <= key.length, prefix.length <= 50
  • key 和 prefix 仅由小写英文字母组成
  • 1 <= val <= 1000
  • 最多调用 50 次 insert 和 sum

二、 方法一:暴力扫描

方法一:
暴力扫描。对哈希表进行增删查改,就是注意找到​​​prefix​​开头的键key的操作就行。

三、代码

class MapSum {
private:
unordered_map<string, int>mp;
public:
MapSum() {

}

void insert(string key, int val) {
mp[key] = val;
}

int sum(string prefix) {
int ans = 0;
for(auto &[key, val]: mp){
//右下标为后一位
if(key.substr(0, prefix.size()) == prefix){
ans += val;
}
}
return ans;
}
};

/**
* Your MapSum object will be instantiated and called as such:
* MapSum* obj = new MapSum();
* obj->insert(key,val);
* int param_2 = obj->sum(prefix);
*/

四、方法二:字典树

方法二:字典树。

更新每个前缀​​prefix[i]​​​值​​delta​​:

  • 如果key不存在,则​​delta=val​
  • 如果key存在,则key对应的前缀值都增加​​val - cnt[key]​

​sum​​操作就直接在前缀树上搜索给定的前缀对应的值,如果给定的前缀不在前缀树中则返回0。

struct TrieNode{
int val;
TrieNode *next[26];
TrieNode(){
this->val = 0;
for(int i = 0; i < 26; i++){
this->next[i] = NULL;
}
}
};
class MapSum {
private:
TrieNode* root;
unordered_map<string, int> cnt;
public:
MapSum() {
this->root = new TrieNode();
}

void insert(string key, int val) {
int data = val;
if(cnt.count(key)){
data -= cnt[key];
}
cnt[key] = val;
TrieNode* node = root;
for(auto c: key){
if(node->next[c - 'a'] == NULL){
node->next[c - 'a'] = new TrieNode;
}
node = node->next[c - 'a'];
node->val += data;
}
}

int sum(string prefix) {
TrieNode* node = root;
for(auto c: prefix){
if(node->next[c - 'a'] == NULL){
return 0;
}else{
node = node->next[c - 'a'];
}
}
return node->val;
}
};

/**
* Your MapSum object will be instantiated and called as such:
* MapSum* obj = new MapSum();
* obj->insert(key,val);
* int param_2 = obj->sum(prefix);
*/