题目描述
如果数据结构中有任何与word
匹配的字符串,则bool search(word)
返回true
,否则返回false
。 单词可能包含点“。” 点可以与任何字母匹配的地方。
请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。
实现词典类 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
算法分析
字典树问题
- 1、先定义一个结构点表示某一个树的某一个结点,
is_end
表示从根结点到该位置是否存在有一个单词,该节点有26
个儿子,分别对应'a'
到'z'
- 2、
insert()
操作,从根结点出发,沿着字符串的字符一直往下走,若某一字符不存在,则直接把它创建出来,继续走下去,走完了整个单词,标记最后的位置的is_end = true
- 3、
search()
操作,从根结点出发往下dfs
搜索,dfs(root, word, x)
,root
表示枚举到当前结点,word
表示搜索的单词,x
表示当前搜索到word
的哪个位置,需要通过word[x]
字符找到root
对应哪个儿子,分两种情况- (1)、当前字符
word[x]
不是'.'
,找到字符对应的root.son
的位置,若存在该字符则继续搜索下去,不存该字符则return false
- (2)、当前字符
word[x]
是'.'
,则表示word[x]
可以是root
的任意一个儿子,枚举所有儿子,若该儿子不为null
,则直接dfs
跳到下一层dfs(root.son[i], word, x + 1)
判断,若存在一个儿子能搜索成功则return true
,否则return false
- (1)、当前字符
时间复杂度
插入操作:$O(n)$,n表示插入的字符串的长度
搜索操作:$O(S)$, 由于存在通配符,因此有可能遍历这个歌字典树,S表示整个字典树的字符数量
Java 代码
class WordDictionary {
Node root;
/** Initialize your data structure here. */
public WordDictionary() {
root = new Node();
}
/** Adds a word into the data structure. */
public void addWord(String word) {
Node p = root;
for(int i = 0;i < word.length();i ++)
{
int u = word.charAt(i) - 'a';
if(p.son[u] == null) p.son[u] = new Node();
p = p.son[u];
}
p.is_end = true;
}
/** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
public boolean search(String word) {
return dfs(root, word, 0);
}
static boolean dfs(Node root, String word, int x)
{
if(x == word.length()) return root.is_end;
if(word.charAt(x) != '.')
{
int u = word.charAt(x) - 'a';
if(root.son[u] == null) return false;
return dfs(root.son[u], word, x + 1);
}
else
{
for(int i = 0;i < 26;i ++)
{
if(root.son[i] != null && dfs(root.son[i], word, x + 1))
return true;
}
return false;
}
}
}
class Node
{
boolean is_end;
Node[] son = new Node[26];
Node()
{
for(int i = 0;i < 26;i ++) son[i] = null;
is_end = false;
}
}
/**
* Your WordDictionary object will be instantiated and called as such:
* WordDictionary obj = new WordDictionary();
* obj.addWord(word);
* boolean param_2 = obj.search(word);
*/