LC 336. Palindrome Pairs (Trie, Manacher)

link

class Solution {
public:
struct TrieNode{
    TrieNode* children[26];
    int id;
    TrieNode(){
        id=-1;
        for(int i=0;i<26;i++) children[i]=nullptr;
    }
};
    TrieNode* root;
    vector<vector<int>> palindromePairs(vector<string>& words) {
        root=new TrieNode();
        for(int i=0;i<words.size();i++){
            build(words[i],i);
        }
        vector<vector<int>> res;
        for(int i=0;i<words.size();i++){
            if(words[i]=="") continue;
            auto rec1=findmaxlen(words[i]);
            string rs=words[i];
            reverse(rs.begin(),rs.end());
            auto rec2=findmaxlen(rs);
            int len=words[i].size();
            if(rec1[len-1]==len){
                if(root->id!=-1){
                    res.push_back({i,root->id});
                    res.push_back({root->id,i});
                }
            }
            int id=find(words[i],0,words[i].size()-1);
            if(id!=-1 && id>i){
                res.push_back({i,id});
                res.push_back({id,i});
            }
            
            for(int j=0;j<len-1;j++){
                if(rec2[j]==j+1){
                    int id=find(words[i],0,len-j-2);
                    if(id!=-1) res.push_back({i,id});
                }
            }
            for(int j=0;j<len-1;j++){
                if(rec1[j]==j+1){
                    int id=find(words[i],j+1,len-1);
                    if(id!=-1) res.push_back({id,i});
                }
            }
        }
        return res;
    }

    int find(string& s, int left, int right){
        TrieNode* cur=root;
        for(int i=right;i>=left;i--){
            char c=s[i];
            if(cur->children[c-'a']==nullptr) return -1;
            cur=cur->children[c-'a'];
        }
        return cur->id;
    }

    void build(string& s, int idx){
        TrieNode* cur=root;
        for(char c:s){
            if(cur->children[c-'a']==nullptr){
                cur->children[c-'a']=new TrieNode();
            }
            cur=cur->children[c-'a'];
        }
        cur->id=idx;
    }

    vector<int> findmaxlen(string& s){
        int n=s.size();
        vector<int> res(n);
        string tmp="#";
        for(char c:s){
            tmp.push_back(c);
            tmp.push_back('#');
        }
        int m=tmp.size();
        vector<int> T(m);
        int mid=0;
        int rightB=0;
        for(int i=1;i<m;i++){
            if(i<rightB){
                T[i]=min(rightB-i,T[2*mid-i]);
            }
            while(i-T[i]>=0 && i+T[i]<m && tmp[i-T[i]]==tmp[i+T[i]]){
                T[i]++;
            }
            T[i]--;
            res[(i+T[i]-1)/2]=max(res[(i+T[i]-1)/2],T[i]);
            if(i+T[i]>rightB){
                mid=i;
                rightB=i+T[i];
            }
        }
        return res;
    }
};
原文地址:https://www.cnblogs.com/FEIIEF/p/13445072.html