• 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】Sum Root to Leaf Numbers(hard)
    【leetcode】First Missing Positive(hard) ☆
    【leetcode】Next Permutation(middle)
    【好玩的应用】QQ连连看辅助工具
    【leetcode】Binary Tree Preorder Traversal (middle)★
    【leetcode】Reverse Words in a String(hard)☆
    【leetcode】Same Tree(easy)
    【leetcode】Factorial Trailing Zeroes(easy)
    【leetcode】Maximum Gap(hard)★
    Behavioral模式之Chain of Responsibility模式
  • 原文地址:https://www.cnblogs.com/yfceshi/p/7217085.html
Copyright © 2020-2023  润新知