LeetCode 208. Implement Trie (Prefix Tree)
Posted yfceshi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 208. Implement Trie (Prefix Tree)相关的知识,希望对你有一定的参考价值。
字典树。
測试中有:aaaaaaaaaaa... 的输入,假设每一个节点用定长数组存储孩子的话。那就是26^len的空间复杂度(len为输入的长度),内存会不够的。
所以用map<char, TrieNode*>保存其孩子。
第三遍(将第二遍中search和startsWith的行为抽象成searchNode方法):
struct TrieNode { map<char, shared_ptr<TrieNode>> children; bool is_word = false; }; class Trie { public: Trie(): root(shared_ptr<TrieNode>(new TrieNode)) {} // Inserts a word into the trie. void insert(string word) const { if (word.empty()) { return ; } auto node = root; for (size_t i = 0; i < word.size(); node = node->children[word[i ++]]) { if (node->children.find((word[i])) == node->children.end()) { node->children[word[i]] = shared_ptr<TrieNode>(new TrieNode); } } node->is_word = true; } // Returns if the word is in the trie. bool search(string word) const { auto node = searchNode(word); return node!=nullptr && node->is_word; } // Returns if there is any word in the trie // that starts with the given prefix. bool startsWith(string prefix) const { return searchNode(prefix) != nullptr; } private: shared_ptr<TrieNode> searchNode(string word) const { auto node = root; for (size_t i = 0; i < word.size(); node = node->children[word[i ++]]) { if (node->children.find(word[i]) == node->children.end()) { return nullptr; } } return node; } shared_ptr<TrieNode> root; };第二遍(将第一次代码中的尾递归改成了迭代,速度从270ms提升到了200ms):
struct TrieNode { map<char, shared_ptr<TrieNode>> children; bool is_word = false; }; class Trie { public: Trie(): root(shared_ptr<TrieNode>(new TrieNode)) {} // Inserts a word into the trie. void insert(string word) const { if (word.empty()) { return ; } auto node = root; for (size_t i = 0; i < word.size(); node = node->children[word[i ++]]) { if (node->children.find((word[i])) == node->children.end()) { node->children[word[i]] = shared_ptr<TrieNode>(new TrieNode); } } node->is_word = true; } // Returns if the word is in the trie. bool search(string word) const { // no special judge for empty word here auto node = root; for (size_t i = 0; i < word.size(); node = node->children[word[i ++]]) { if (node->children.find(word[i]) == node->children.end()) { return false; } } return node->is_word; } // Returns if there is any word in the trie // that starts with the given prefix. bool startsWith(string prefix) const { auto node = root; for (size_t i = 0; i < prefix.size(); node = node->children[prefix[i ++]]) { if (node->children.find(prefix[i]) == node->children.end()) { return false; } } return true; } private: shared_ptr<TrieNode> root; };
第一遍:
class TrieNode { public: // Initialize your data structure here. TrieNode() { is_word = false; } void insert(const string& word) { if (!word.empty()) { nodes[word.front()] = nodes[word.front()] != nullptr ? nodes[word.front()] : new TrieNode(); nodes[word.front()]->insert(word.substr(1)); } else { is_word = true; } } bool search(string word) { if (!word.empty()) { if (nodes[word.front()] == nullptr) { return false; } else { return nodes[word.front()]->search(word.substr(1)); } } return is_word; } bool startsWith(string prefix) { if (!prefix.empty()) { if (nodes[prefix.front()] == nullptr) { return false; } else { return nodes[prefix.front()]->startsWith(prefix.substr(1)); } } return true; } // MLE!!! // TrieNode* nodes[26]; map<char, TrieNode*> nodes; bool is_word; }; class Trie { public: Trie() { root = new TrieNode(); } // Inserts a word into the trie. void insert(string word) { root->insert(word); } // Returns if the word is in the trie. bool search(string word) { return root->search(word); } // Returns if there is any word in the trie // that starts with the given prefix. bool startsWith(string prefix) { return root->startsWith(prefix); } private: TrieNode* root; };
以上是关于LeetCode 208. Implement Trie (Prefix Tree)的主要内容,如果未能解决你的问题,请参考以下文章
[LeetCode] 208. Implement Trie (Prefix Tree)
leetcode No208. Implement Trie (Prefix Tree)
[LeetCode] 208(LintCode). Implement Trie(Prefix Tree)
LeetCode 208. Implement Trie (Prefix Tree)