LC.336. 回文对(前缀字典树)

LC.336. 回文对(前缀字典树)

思路:前缀字典树。

考虑回文串对的组成: p a i r ( s 1 , s 2 ) pair(s_1,s_2)

l e n 1 = l e n 2 len_1=len_2 ,则 s 1 s_1 s 2 s_2 的翻转。

l e n 1 > l e n 2 len_1>len_2 ,则 s 1 s_1 s 2 s_2 的翻转+回文串组成。

l e n 1 < l e n 2 len_1<len_2 ,则 s 2 s_2 s 1 s_1 的回文+翻转组成。

因此可以枚举每个子串的前后缀,查找剩余部分的翻转是否存在即可。

时间复杂度: O ( n m 2 ) O(nm^2)

class Solution {
public:
	struct node{
		int ch[26],id;
		node(){id=-1,memset(ch,0,sizeof ch);}
	};
	vector<node>tr;
	void ins(string &s,int num){
		int x=0,l=s.size();
		for(int i=0;i<l;i++){
			int c=s[i]-'a';
			if(!tr[x].ch[c]) tr.emplace_back(),tr[x].ch[c]=tr.size()-1;
			x=tr[x].ch[c];
		}
		tr[x].id=num;
	}
	bool jg(string &s,int l,int r){
		int len=r-l+1;if(len<0) return false;
		for(int i=0;i<len>>1;i++)
			if(s[l+i]!=s[r-i]) return false;
		return true;
	} 
	int Find(string &s,int l,int r){
		int x=0;
		for(int i=r;i>=l;i--){
			int c=s[i]-'a';
			if(!tr[x].ch[c]) return -1;
			x=tr[x].ch[c];
		}
		return tr[x].id;
	}
    vector<vector<int>> palindromePairs(vector<string>& w) {
		tr.emplace_back();
		int n=w.size();
		for(int i=0;i<n;i++) ins(w[i],i);
		vector<vector<int> >ans;
		for(int i=0;i<n;i++){
			int m=w[i].size();
			for(int j=0;j<=m;j++){
				if(jg(w[i],j,m-1)){
					int id=Find(w[i],0,j-1);
					if(~id&&id!=i) ans.push_back({i,id}); 
				}
				if(j&&jg(w[i],0,j-1)){
					int id=Find(w[i],j,m-1);
					if(~id&&id!=i) ans.push_back({id,i}); 
				}
			}
		}
		return ans;
    }
}; 

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/107831725