【LeetCode】Add and Search Word - Data structure design

Design a data structure that supports the following two operations:

void addWord(word)
bool search(word)

search(word) can search a literal word or a regular expression string containing only letters a-z or .. A . means it can represent any one letter.

Example:

addWord("bad")
addWord("dad")
addWord("mad")
search("pad") -> false
search("bad") -> true
search(".ad") -> true
search("b..") -> true

Note:
You may assume that all words are consist of lowercase letters a-z.

题解:可以用trie树也可以用map,trie树要注意search时遇到'.'时要遍历孩子26个节点中非空的那些,只要其中为true即可也就是说就算结果是false也不能直接return false要用res记录所有结果的并集只要其中一个true即可,这是用dfs带有目标string的遍历指针的写法;也可以直接不用index,在dfs里面直接遍历string,然后遇到.才递归,这种情况要注意回溯的情况因为回溯的最终出口就是非递归情况的指针root,所以要return root->isword,前面我最后也写了这句话但是错了因为这是前面所有递归出来的结果也就是前面没有return的那些dfs递归回溯到开始时的root,正确应该是最初那些就应该return,然后出口直接在开头判断index是不是到达string结尾;最快的是map,也就是把长度相同映射到同一个map,然后写个判断长度相同是否相等的方法,思路更加简单了,因为对'.'的处理只要是‘.’的情况都是当成通用符

代码:

//直接dfs里面遍历版本
class TrieNode{
public:
    bool isWord;
    TrieNode* child[26];
    TrieNode():isWord(false){
        memset(child, NULL, sizeof(TrieNode*) * 26); 
    }
    
};
class WordDictionary {
public:
    /** Initialize your data structure here. */
    WordDictionary() {
        root=new TrieNode();
    }
    
    /** Adds a word into the data structure. */
    void addWord(string word) {
        TrieNode* p=root;
        for(auto a:word){
            int i=a-'a';
            if(p->child[i]==nullptr) p->child[i]=new TrieNode();
            p=p->child[i];
        }
        p->isWord=true;
    }
    
    /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
    bool search(string word) {
      
        return dfs(word,root);
    }
    bool dfs(string word,TrieNode* root){
        
        for(int i=0;i<word.size();i++){
            int k=word[i]-'a';
            if(word[i]!='.'){
                if(!root->child[k]) return false;
                root=root->child[k];
            }else{
               bool res=false;
                for(int j=0;j<26;j++){
                    if(root->child[j]) res|=dfs(word.substr(i+1),root->child[j]) ; 
                }
                return res;
            }
        }
        return root->isWord;
    }
   
private:
    TrieNode* root;
};

//dfs里面没有遍历的版本
class TrieNode{
public:
    bool isWord;
    TrieNode* child[26];
    TrieNode():isWord(false){
        memset(child, NULL, sizeof(TrieNode*) * 26); 
    }
    
};
class WordDictionary {
public:
    /** Initialize your data structure here. */
    WordDictionary() {
        root=new TrieNode();
    }
    
    /** Adds a word into the data structure. */
    void addWord(string word) {
        TrieNode* p=root;
        for(auto a:word){
            int i=a-'a';
            if(p->child[i]==nullptr) p->child[i]=new TrieNode();
            p=p->child[i];
        }
        p->isWord=true;
    }
    
    /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
    bool search(string word) {
      
        return dfs(word,0,root);
    }
    bool dfs(string word,int index,TrieNode* root){
       
        if(index==word.size()) return root->isWord;
        
        int i=word[index]-'a';
        if(word[index]!='.'&&root->child[i]) return dfs(word,index+1,root->child[i]);
        else if(word[index]!='.'&&!root->child[i]) return false;
        else{
            bool res=false;
            for(int j=0;j<26;j++){
                if(root->child[j]) res|=dfs(word,index+1,root->child[j]);
            }
            return res;
        }
        
    }
private:
    TrieNode* root;
};
//map版本
class WordDictionary {
public:
    WordDictionary() {}
    
    void addWord(string word) {
        words[word.size()].push_back(word);
    }
    
    bool search(string word) {
        for(auto s: words[word.size()]) if(isEqual(s, word)) return true;
        return false;
    }
    
private:
    unordered_map<int, vector<string>>words;
    
    bool isEqual(string a, string b){
        for(int i = 0; i < a.size(); i++){
            if(b[i] == '.') continue;
            if(a[i] != b[i]) return false;
        }
        return true;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值