力扣每日一题211:添加与搜索单词

题目

难度:中等

相关标签

相关企业

提示

请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。

实现词典类 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题。

http://t.csdnimg.cn/KXxjl

匹配的话用递归的方法。

若匹配到最后一个字母并且当前节点标记为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);
 */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值