题目
难度:中等
相关标签
相关企业
提示
请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。
实现词典类 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"); // 返回 False wordDictionary.search("bad"); // 返回 True wordDictionary.search(".ad"); // 返回 True wordDictionary.search("b.."); // 返回 True
提示:
1 <= word.length <= 25
addWord
中的word
由小写英文字母组成search
中的word
由 '.' 或小写英文字母组成- 最多调用
104
次addWord
和search
面试中遇到过这道题?
1/5
是
否
通过次数
87.5K
提交次数
175.1K
通过率
50.0%
要求格式
class WordDictionary {
public:
WordDictionary() {
}
void addWord(string word) {
}
bool search(string word) {
}
};
/**
* Your WordDictionary object will be instantiated and called as such:
* WordDictionary* obj = new WordDictionary();
* obj->addWord(word);
* bool param_2 = obj->search(word);
*/
思路
用哈希表记录孩子节点。插入的时候还是正常插入。不懂的可以看我写的力扣第208题。
匹配的话用递归的方法。
若匹配到最后一个字母并且当前节点标记为true,那么就说明匹配成功。
如果当前字符可以匹配且不是点,就递归匹配下一个字符和孩子节点。
如果当前字符与孩子节点不能匹配,但是当前字符是'.',那就递归调用所有的孩子节点与下一字符匹配,只要有一个匹配成功即可。
其他情况下就代表从当前字符开始匹配失败。
代码
class WordDictionary {
public:
struct Node{
char letter;
bool flag=false;
unordered_map<char,Node*> child;
string val;
int len;
Node() {};
Node(char c) : letter(c) {};
};
Node* root;
WordDictionary() {
root=new Node('#');
}
void addWord(string word) {
int n=word.length();
int i=0;
Node* cur=root;
while( i<n&&(cur->child).find(word[i])!=(cur->child).end() ){
cur=(cur->child)[word[i]];
i++;
}
//word已经在前缀树的路径中
if(i==n){
if(cur->flag==false){
cur->flag=true;
}else{
return ;
}
}else{
while(i<n){
(cur->child)[word[i]]=new Node(word[i]);
cur=(cur->child)[word[i]];
i++;
}
cur->flag=true;
}
}
bool search(string word) {
return match(word,0,root);
}
bool match(string& word,int i,Node* cur){
if(i==word.length()&&cur->flag==true){
return true;
}
if( (cur->child).find(word[i])!=(cur->child).end() ){
cur=(cur->child)[word[i]];
i++;
return match(word,i,cur);
}else if( (cur->child).size()!=0&&word[i]=='.' ){
//匹配完点后,只要有一个方向能匹配即可
i++;
for(auto x:cur->child){
Node* next=x.second;
if( match(word,i,next) ) return true;
}
return false;
}else{//同一层不能匹配并且word[i]不是点,那就宣布从i开始匹配失败
return false;
}
}
};
/**
* Your WordDictionary object will be instantiated and called as such:
* WordDictionary* obj = new WordDictionary();
* obj->addWord(word);
* bool param_2 = obj->search(word);
*/