676. 实现一个魔法字典 (字典树)

01题目描述

在这里插入图片描述

02整体思想

在这里插入图片描述

3.bool _search_2(string & word) 原理如图示

image.png

image.png
image.png

04 bool _search_2(string & word) 对应的代码逻辑如下

    bool _search_2(string & word){
            TrieNode *cur=this; // cur一开始 指向根节点,然后分别将第1、2、3、...个字母改变,判断是否能匹配成功
            for( int j=0;j<word.size();j++){
                int idx=word[j]-'a';
                if(_search_1(cur,word, j)) return true; //cur 起始指向根节点,word[0]字母改变, 判断余下的字母能否完全匹配
                cur=cur->nodes[idx];//说明word[j]改变无法匹配成功
                
                if(cur==nullptr) return false;
            }
            return false;
    }

05 _search_1(cur,word, j)的原理

改变word[j]cur 的非空子节点a,返回以a的子树中是否包含word[j+1:-1]
在这里插入图片描述

06 bool _search(TrieNode *cur, string & word , int i)的原理

//判断字符串 word[i:-1]是否是在以cur 为根结点的前缀树中
    bool _search(TrieNode *cur, string & word , int i){
        for(int j=i;j<word.size();j++){
      
            int idx=word[j]-'a';
            if(cur->nodes[idx]==nullptr) return false;
            cur=cur->nodes[idx];
        }
        return cur->tag==1;
    }

07 完整代码

class TrieNode{
public:
    vector<TrieNode*> nodes;
    bool tag=0;
    TrieNode():nodes(26,nullptr){}
// 字典树插入字符串
    void insert(string & word){
        TrieNode *cur=this;
        for(auto ch:word){
            int idx=ch-'a';
            if(cur->nodes[idx]==nullptr) cur->nodes[idx]=new TrieNode();
            cur=cur->nodes[idx];
        }
        cur->tag=1;
    }
//判断字符串 word[i:-1]是否是在以cur 为根结点的前缀树中
    bool _search(TrieNode *cur, string & word , int i){
        for(int j=i;j<word.size();j++){
      
            int idx=word[j]-'a';
            if(cur->nodes[idx]==nullptr) return false;
            cur=cur->nodes[idx];
        }
        return cur->tag==1;
    }
//当前位于前缀树的节点为cur, 且第i个为替换字母,即cur->nodes[i]==nullptr,考虑word[i+1]是否和cur->nodes[j]  匹配;
//例子 bcd  ba
    bool _search_1(TrieNode * cur,string & word, int  i)  {
        for(int j=0;j<26;j++){
            if(j==word[i]-'a' || cur->nodes[j]==nullptr) continue;
            if(_search(cur->nodes[j],word,i+1)) {
            return true;}
        }
        return false;
    }

    bool _search_2(string & word){
            TrieNode *cur=this;
            for( int j=0;j<word.size();j++){
                int idx=word[j]-'a';
                if(_search_1(cur,word, j)) return true;
                cur=cur->nodes[idx];
                if(cur==nullptr) return false;
            }
            return false;
    }
    bool search(string & word){
        int sz=word.size();
        TrieNode *cur=this;
        return _search_2(word);
    }
};
class MagicDictionary {
public:
    /** Initialize your data structure here. */
    TrieNode *root;
    MagicDictionary() {
        root=new TrieNode();
    }
    
    void buildDict(vector<string> dictionary) {
        for(auto & dic:dictionary){
            root->insert(dic);
        } 
    }
    
    bool search(string searchWord) {
        return root->search(searchWord);
    }
};

/**
 * Your MagicDictionary object will be instantiated and called as such:
 * MagicDictionary* obj = new MagicDictionary();
 * obj->buildDict(dictionary);
 * bool param_2 = obj->search(searchWord);
 */

力扣

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值