677. 键值映射(trie map)
labuladong 题解
难度中等
设计一个 map ,满足以下几点:
- 字符串表示键,整数表示值
- 返回具有前缀等于给定字符串的键的值的总和
实现一个 MapSum
类:
MapSum()
初始化MapSum
对象void insert(String key, int val)
插入key-val
键值对,字符串表示键key
,整数表示值val
。如果键key
已经存在,那么原来的键值对key-value
将被替代成新的键值对。int sum(string prefix)
返回所有以该前缀prefix
开头的键key
的值的总和。
示例 1:
输入: ["MapSum", "insert", "sum", "insert", "sum"] [[], ["apple", 3], ["ap"], ["app", 2], ["ap"]] 输出: [null, null, 3, null, 5] 解释: MapSum mapSum = new MapSum(); mapSum.insert("apple", 3); mapSum.sum("ap"); // 返回 3 (apple = 3) mapSum.insert("app", 2); mapSum.sum("ap"); // 返回 5 (apple + app = 3 + 2 = 5)
from collections import defaultdict class Trie: def __init__(self): self.children = defaultdict(Trie) self.is_end = False self.val = 0 class MapSum: def __init__(self): self.root = Trie() def insert(self, key: str, val: int) -> None: node = self.root for ch in key: node = node.children[ch] node.is_end = True node.val = val def sum(self, prefix: str) -> int: def dfs(root): res = 0 if root == None: return 0 if root.is_end: res = root.val for kk in root.children.keys(): node = root.children[kk] res+=dfs(node) return res #找到前缀叶子节点,然后遍历以叶子节点为起始,找所有的孩子 node = self.root for ch in prefix: node = node.children[ch] #记录符合前缀要求的叶子节点 val 和 res = 0 res += dfs(node) return res # Your MapSum object will be instantiated and called as such: # obj = MapSum() # obj.insert(key,val) # param_2 = obj.sum(prefix)
1 struct TrieNode { 2 int val; 3 vector<TrieNode*> children; 4 TrieNode(int val) { 5 this->val = 0; 6 this->children = vector<TrieNode*>(26,nullptr); 7 } 8 }; 9 10 class MapSum { 11 private: 12 int dfs(TrieNode* node) { 13 if(node == nullptr) return 0; 14 15 int res = node->val; 16 for(auto& c_node : node->children) { 17 if(c_node != nullptr) { 18 res += dfs(c_node); 19 } 20 } 21 return res; 22 } 23 24 public: 25 TrieNode* root; 26 /** Initialize your data structure here. */ 27 MapSum() { 28 root = new TrieNode(0); 29 } 30 31 void insert(string key, int val) { 32 TrieNode* curr = root; 33 for(auto& k : key) { 34 if(curr->children[k - 'a'] == nullptr) { 35 curr->children[k - 'a'] = new TrieNode(0); 36 } 37 curr = curr->children[k - 'a']; 38 } 39 curr->val = val; 40 } 41 42 int sum(string prefix) { 43 int res = 0; 44 45 //找到前缀叶子节点,然后遍历以叶子节点为起始,找所有的孩子 46 TrieNode* node = root; 47 for(auto ch : prefix) { 48 if(node->children[ch - 'a'] == nullptr) return 0; 49 node = node->children[ch - 'a']; 50 } 51 // 记录符合前缀要求的叶子节点 val 和 52 res += node->val; 53 for(auto& c_node : node->children) res += dfs(c_node); 54 return res; 55 } 56 }; 57 58 /** 59 * Your MapSum object will be instantiated and called as such: 60 * MapSum* obj = new MapSum(); 61 * obj->insert(key,val); 62 * int param_2 = obj->sum(prefix); 63 */