leetcode 208. 实现 Trie (前缀树)
问题描述
实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。
示例:
Trie trie = new Trie();
trie.insert("apple");
trie.search("apple"); // 返回 true
trie.search("app"); // 返回 false
trie.startsWith("app"); // 返回 true
trie.insert("app");
trie.search("app"); // 返回 true
说明:
你可以假设所有的输入都是由小写字母 a-z 构成的。
保证所有输入均为非空字符串。
代码
class Trie {
public:
vector<string> s;
/** Initialize your data structure here. */
Trie() {
}
/** Inserts a word into the trie. */
void insert(string word) {
s.push_back(word);
}
/** Returns if the word is in the trie. */
bool search(string word) {
for(auto i:s){
if(i == word)return true;
}
return false;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix) {
int n = prefix.size(),j;
for(auto i:s)
{
if(i.size() < n)continue;
/*for(j = 0; j < n; ++j)
{
if(i[j] != prefix[j])break;
}
if(j == n)return true;*/
if(i.substr(0,n)==prefix)return true;
}
return false;
}
};
/**
* Your Trie object will be instantiated and called as such:
* Trie* obj = new Trie();
* obj->insert(word);
* bool param_2 = obj->search(word);
* bool param_3 = obj->startsWith(prefix);
*/
直接这样写会超出时间限制,但是把
for(auto i:s)
改为
for(auto &i:s)
因为不带&号的相当于建立了一个副本,而带&是在原数据上操作。结果为
执行用时 :1608 ms, 在所有 C++ 提交中击败了5.03%的用户
内存消耗 :22.7 MB, 在所有 C++ 提交中击败了100.00%的用户
如果使用注释中的代码
class Trie {
public:
vector<string> s;
/** Initialize your data structure here. */
Trie() {
}
/** Inserts a word into the trie. */
void insert(string word) {
s.push_back(word);
}
/** Returns if the word is in the trie. */
bool search(string word) {
for(auto &i:s){
if(i == word)return true;
}
return false;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix) {
int n = prefix.size(),j;
for(auto &i:s)
{
if(i.size() < n)continue;
for(j = 0; j < n; ++j)
{
if(i[j] != prefix[j])break;
}
if(j == n)return true;
//if(i.substr(0,n)==prefix)return true;
}
return false;
}
};
/**
* Your Trie object will be instantiated and called as such:
* Trie* obj = new Trie();
* obj->insert(word);
* bool param_2 = obj->search(word);
* bool param_3 = obj->startsWith(prefix);
*/
结果为
执行用时 :700 ms, 在所有 C++ 提交中击败了5.03%的用户
内存消耗 :22.6 MB, 在所有 C++ 提交中击败了100.00%的用户
代码2
class Trie {
public:
bool isEnd;
Trie *next[26];//如next[i]非空,相当于存储了26个字母中第i个字母
/** Initialize your data structure here. */
Trie() {
isEnd = false;
memset(next,0,sizeof(next));
}
/** Inserts a word into the trie. */
void insert(string word) {
Trie *node = this;//根节点为空
for(char s:word)
{
if(!node->next[s-'a'])
{
node->next[s-'a'] = new Trie();
}
node = node->next[s-'a'];
}
node->isEnd = true;
}
/** Returns if the word is in the trie. */
bool search(string word) {
Trie *node = this;
for(auto &s:word)
{
node = node->next[s-'a'];
if(!node)return false;
}
return node->isEnd;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix) {
Trie *node = this;
for(auto &s:prefix)
{
node = node->next[s-'a'];
if(!node)return false;
}
return true;
}
};
/**
* Your Trie object will be instantiated and called as such:
* Trie* obj = new Trie();
* obj->insert(word);
* bool param_2 = obj->search(word);
* bool param_3 = obj->startsWith(prefix);
*/
结果
执行用时 :124 ms, 在所有 C++ 提交中击败了44.78%的用户
内存消耗 :43.6 MB, 在所有 C++ 提交中击败了54.55%的用户