677. Map Sum Pairs 發表於 2023-02-13 | 分類於 leetcode problemsolution123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156class TrieNode{public: bool isWord; int val; TrieNode* children[26]; TrieNode(){ val = 0; isWord = false; for(TrieNode * & child :children) child = nullptr; }};class Trie{private: TrieNode *root;public: Trie(){ root = new TrieNode(); } TrieNode* put(TrieNode* node, string key, int val, int i){ if(node == nullptr) node = new TrieNode(); if(i == key.size()){ node->val = val; return node; } char c = key[i]; node->children[c-'a'] = put(node->children[c-'a'], key, val, i+1); return node; } void put(string key, int val){ // iterative // TrieNode *p = root; // for(char c:key){ // if(!p->children[c-'a']) p->children[c-'a'] = new TrieNode(); // p=p->children[c-'a']; // } // p->val = val; // p->isWord = true; //recursive root = put(root, key, val, 0); } bool search(string word){ TrieNode *p = root; for(char c:word){ if(!p->children[c-'a']) return false; p=p->children[c-'a']; } return p->isWord; } // 從節點 node 開始搜索 key,如果存在返回對應節點,否則返回 null TrieNode* getNode(TrieNode *node, string key){ TrieNode *p = node; // 從節點 node 開始搜索 key for (int i = 0; i < key.size(); i++) { if (!p ) { // 無往向下搜索 return nullptr; } // 向下搜索 char c = key[i]; p = p->children[c-'a']; } return p; } // 搜索 key 對應的值,不存在則返回 null int get(string prefix){ TrieNode * x = getNode(root, prefix); if (x == nullptr || x->val == 0) { // x 為空或 x 的 val 字段為空都说明 key 没有對應的值 return 0; } return x->val; } // 搜尋所有前綴為prefix 所有鍵 // keysWithPrefix("th") -> ["that", "the", "them"] vector<string> keysWithPrefix(string prefix){ vector<string> ret; TrieNode * x = getNode(root, prefix); if(x==nullptr) return ret; // DFS 遍歷以 x 為根的這棵 Trie 樹 traverse(x, prefix, ret); return ret; } // 遍歷以 node 節點為根的 Trie 樹,找到所有鍵 void traverse(TrieNode *node, string path, vector<string> & ret){ if(node == nullptr) return; if(node->val!=0) ret.push_back(path); for(char c = 'a';c<='z' ; ++c){ path.push_back(c); traverse(node->children[c-'a'], path, ret); path.pop_back(); } } // 遍歷函数,嘗試在「以 node 為根的 Trie 樹中」匹配 pattern[i..] void traverse(TrieNode * node, string path, string pattern, int i, vector<string> & ret){ if(node==nullptr) return; if(i==pattern.size()){ if(node->val!=0){ ret.push_back(path); } return; } char c = pattern[i]; if(c=='.'){ for(char j = 'a' ;j<='z';++j){ path.push_back(j); traverse(node->children[j-'a'], path,pattern, i+1, ret); path.pop_back(); } } else{ path.push_back(c); traverse(node->children[c-'a'], path,pattern, i+1, ret); path.pop_back(); } } };class MapSum {private: Trie *root;public: MapSum() { root = new Trie(); } void insert(string key, int val) { root->put(key, val); } int sum(string prefix) { vector<string> keys = root->keysWithPrefix(prefix); int ret = 0; for(string key:keys){ ret+= root->get(key); } return ret; }};/** * Your MapSum object will be instantiated and called as such: * MapSum* obj = new MapSum(); * obj->insert(key,val); * int param_2 = obj->sum(prefix); */