LeetCode 1032. 字符流(trie)

题意:
按下述要求实现 StreamChecker 类:

StreamChecker(words):构造函数,用给定的字词初始化数据结构。
query(letter):如果存在某些 k >= 1,
可以用查询的最后 k个字符(按从旧到新顺序,包括刚刚查询的字母)拼写出给定字词表中的某一字词时,返回 true。
否则,返回 false。
 

示例:

StreamChecker streamChecker = new StreamChecker(["cd","f","kl"]); // 初始化字典
streamChecker.query('a');          // 返回 false
streamChecker.query('b');          // 返回 false
streamChecker.query('c');          // 返回 false
streamChecker.query('d');          // 返回 true,因为 'cd' 在字词表中
streamChecker.query('e');          // 返回 false
streamChecker.query('f');          // 返回 true,因为 'f' 在字词表中
streamChecker.query('g');          // 返回 false
streamChecker.query('h');          // 返回 false
streamChecker.query('i');          // 返回 false
streamChecker.query('j');          // 返回 false
streamChecker.query('k');          // 返回 false
streamChecker.query('l');          // 返回 true,因为 'kl' 在字词表中。
 

提示:

1 <= words.length <= 2000
1 <= words[i].length <= 2000
字词只包含小写英文字母。
待查项只包含小写英文字母。
待查项最多 40000 个。
解法:
发现问题就是求查询序列的某个后缀是否在字典中.

我们可以对字典中的每个串逆序建立trie,
那么对于询问,我们只需要对查询序列 逆序的从trie的根开始走,
如果走到了串结尾的标记点,说明存在这样满足条件的串,
如果走不了了或者走完了还没有标记,那么就不存在满足条件的串.
code:
struct Trie{
    static const int maxm=4e4+5;
    int a[maxm][26],tot;
    bool val[maxm];
    int last[maxm],num;
    void init(){
        for(int i=0;i<=tot;i++){
            val[i]=0;
            for(int j=0;j<26;j++){
                a[i][j]=0;
            }
        }
        num=0;
        tot=0;
    }
    void add(string&s){
        int node=0;
        int len=s.size();
        for(int i=len-1;i>=0;i--){
            int v=s[i]-'a';
            if(!a[node][v]){
                a[node][v]=++tot;
            }
            node=a[node][v];
        }
        val[node]=1;
    }
    void insert(char&c){
        last[++num]=c-'a';
    }
    int ask(){
        int node=0;
        for(int i=num;i>=1;i--){
            int v=last[i];
            if(!a[node][v])return 0;
            node=a[node][v];
            if(val[node])return 1;
        }
        return 0;
    }
}T;
class StreamChecker {
public:
    StreamChecker(vector<string>& words) {
        T.init();
        for(auto &i:words){
            T.add(i);
        }
    }    
    bool query(char letter) {
        T.insert(letter);
        if(T.ask())return 1;
        return 0;
    }
};

/**
 * Your StreamChecker object will be instantiated and called as such:
 * StreamChecker* obj = new StreamChecker(words);
 * bool param_1 = obj->query(letter);
 */

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值