欢迎访问LeetCode题解合集
题目描述
请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。
实现词典类 WordDictionary
:
-
WordDictionary()
初始化词典对象 -
void addWord(word)
将word
添加到数据结构中,之后可以对它进行匹配 -
bool search(word)
如果数据结构中存在字符串与word
匹配,则返回true
;否则,返回false
。word
中可能包含一些'.'
,每个.
都可以表示任何一个字母。
示例:
输入:
["WordDictionary","addWord","addWord","addWord","search","search","search","search"]
[[],["bad"],["dad"],["mad"],["pad"],["bad"],[".ad"],["b.."]]
输出:
[null,null,null,null,false,true,true,true]
解释:
WordDictionary wordDictionary = new WordDictionary();
wordDictionary.addWord("bad");
wordDictionary.addWord("dad");
wordDictionary.addWord("mad");
wordDictionary.search("pad"); // return False
wordDictionary.search("bad"); // return True
wordDictionary.search(".ad"); // return True
wordDictionary.search("b.."); // return True
提示:
-
1 <= word.length <= 500
-
addWord
中的word
由小写英文字母组成 -
search
中的word
由 ‘.’ 或小写英文字母组成 -
最多调用
50000
次addWord
和search
题解:
Trie树的应用。
因为插入的 word
都是小写英文字母,所以可以使用 trie树
来快速查询。
trie树
构建过程参考 实现 Trie (前缀树) 。
查询时,递归进行,遇到 .
通配符时,枚举 0~25
每个节点,判断是否能匹配。
插入时间复杂度:$O(L)$,L
指字符串长度
查询时间复杂度:$O(n * L)$,n
指 trie树
中的节点个数
额外空间复杂度:$O(n * L)$
class WordDictionary {
WordDictionary *son[26]{nullptr};
bool is_tail {false};
public:
WordDictionary() { }
void addWord(string word) {
auto root = this;
int u;
for( int i = 0; word[i]; ++i ) {
u = word[i] - 'a';
if ( !root->son[u] )
root->son[u] = new WordDictionary();
root = root->son[u];
}
root->is_tail = true;
}
bool dfs( WordDictionary* root, const string& word, int p ) {
if ( p >= word.size() ) return root->is_tail;
if ( word[p] == '.' ) {
for ( int i = 0; i < 26; ++i )
if ( root->son[i] && dfs( root->son[i], word, p + 1 ) )
return true;
} else {
int u = word[p] - 'a';
if ( root->son[u] )
return dfs( root->son[u], word, p + 1 );
else return false;
}
return false;
}
bool search(string word) {
return dfs( this, word, 0 );
}
};
/*
时间:72ms,击败:93.86%
内存:42.2MB,击败:79.90%
*/