LeetCode 745. 前缀和后缀搜索***

具体思路:

又一个见到的升级版字典树问题;

难点不在于字典树,而在于前缀后缀判断;

如果建两棵树必定会超时;

这里有一个前后缀一起判断的方法;

对于字符串"abc";

可以构造"abc#abc";

之后构造:

abc#abc
bc#abc
c#abc
#abc

查询后缀前缀必定是上述四个的部分子串;

同时建树的时候设定index进行覆盖,这样可以保证索引最大的相同树结构可以覆盖之前的索引记录;

并且一定要记住,要逐层覆盖索引,因为前缀后缀拼合可能只是子序列,并非完整路径;

具体代码:

struct node{
    node(){
        children.resize(26,nullptr);
        isend=false;
        
        str="";
    }

    void insert(string& s){
        node* root=this;
        for(auto& ch:s){
            int index=ch-'a';
            if(root->children[index]==nullptr){
                root->children[index]=new node();
            }
            root=root->children[index];
        }
        root->isend=true;
        root->str=s;
    }

    vector<string> nodefind(string& str){
        vector<string>ret;
        node* root=this;
        for(auto& ch:str){
            int index=ch-'a';
            if(root->children[index]==nullptr){
                return ret;
            }
            root=root->children[index];
        }
        deep_find(root, ret);
        return ret;
    }

    void deep_find(node* root,vector<string>& ret){
        if(!root)
            return;
        if(root->isend){
            ret.push_back(root->str);
        }
        for(auto& p:root->children){
            deep_find(p, ret);
        }
    }

    vector<node*> children;
    bool isend;
    string str;
};

class WordFilter {
public:
    WordFilter(vector<string>& words) {
        frontroot=new node();
        forwardroot=new node();
        int cnt=0;
        for(auto& str:words){
            frontroot->insert(str);
            fump[str]=cnt;
            reverse(str.begin(), str.end());
            forwardroot->insert(str);
            bump[str]=cnt;
            cnt++;
        }
    }
    
    int f(string prefix, string suffix) {
        reverse(suffix.begin(),suffix.end());
        vector<string>pre=frontroot->nodefind(prefix);
        vector<string>suf=forwardroot->nodefind(suffix);
        map<int,int>mp;
        for(auto& str:pre){
            int index=fump[str];
            mp[index]++;
        }
        for(auto& str:suf){
            int index=bump[str];
            mp[index]++;
        }
        int maxn=-1;
        for(auto it=mp.begin();it!=mp.end();it++){
            if(it->second==2){
                maxn=it->first;
            }
        }
        return maxn;
    }
private:
    unordered_map<string,int>fump;
    unordered_map<string,int>bump;
    node* frontroot;
    node* forwardroot;
};

/**
 * Your WordFilter object will be instantiated and called as such:
 * WordFilter* obj = new WordFilter(words);
 * int param_1 = obj->f(prefix,suffix);
 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值