题意:给定一系列单词,若某两个单词拼接起来是回文串,则把这两个单词下标组成的二元组成为“回文对”,找出所有的回文对。
方法:其实很简单,对于任意两个单词a,b,假设b的长度大于a。则a+b是回文串的条件是字符串b从最后一位到前面某一位反转字符串是a并且b串中该位置到第一位是回文串,若b+a是回文串的条件是字符串b从第一位开始到某一位反转的字符串是a并且b串中该位置到最后一位的串是回文串。所以对于每一个串,只要分情况判断即可。
有两个坑:
1、空串的情形。空串和任何回文字符串拼接都是回文串
2、若a是b的反转串,则第一种情况时b的下标是[b.length()-1,0],第二种情况的下标是[1,b.length()-1]。否则答案会输出两遍。
如何保存呢?用trie树和用set都可以,貌似用set效率高一点,还好写。我吭哧吭哧(keng chi)把trie树给写了,发现效率还没有set高,泪崩。。。我就贴一下我用trie树的代码吧。
struct node
{
struct node *next[26];
int level;
int index;
node(int q)
{
level=q;
index=-1;
int i;
for(i=0;i<26;i++) next[i]=NULL;
}
};
bool check(string s,int start,int end)
{
if(end<=start) return true;
string t=s.substr(start,end-start+1);
int i;
for(i=0;i<t.length()/2;i++) if(t[i]!=t[t.length()-1-i]) return false;
return true;
}
vector<vector<int>> getPalindromePairs(vector<string>& words,int tag)
{
vector<vector<int>> ans;
vector<int> res;
int i,j,k;
struct node *tree=new node(-1),*temp;
for(i=0;i<words.size();i++)
{
temp=tree;
for(j=0;j<words[i].length();j++)
{
if(temp->next[words[i][j]-'a']==NULL) temp->next[words[i][j]-'a']=new node(j);
temp=temp->next[words[i][j]-'a'];
}
temp->index=i;
}
for(i=0;i<words.size();i++)
{
temp=tree;
for(j=words[i].length()-1;j>=tag+0;j--)
{
temp=temp->next[words[i][j]-'a'];
if(temp==NULL) break;
if(temp->index!=i&&temp->index!=-1&&check(words[i],0,j-1))
{
res.clear();
res.push_back(temp->index);
res.push_back(i);
ans.push_back(res);
}
}
}
deleteTree(tree);
return ans;
}
void deleteTree(struct node * tree)
{
int i;
for(i=0;i<26;i++) if(tree->next[i]!=NULL) deleteTree(tree->next[i]);
delete tree;
}
vector<vector<int>> palindromePairs(vector<string>& words)
{
vector<vector<int>> ans1;
ans1=getPalindromePairs(words,0);
vector<int> temp;
int i,j,k,empty=-1;
for(i=0;i<words.size();i++)
{
if(words[i].length()==0) empty=i;
for(j=0;j<words[i].length()/2;j++) swap(words[i][j],words[i][words[i].length()-1-j]);
}
vector<vector<int>> ans2=getPalindromePairs(words,1);
for(i=0;i<ans2.size();i++)
{
temp.clear();
temp.push_back(ans2[i][1]);
temp.push_back(ans2[i][0]);
ans1.push_back(temp);
}
if(empty!=-1)
{
for(i=0;i<words.size();i++)
{
if(empty!=i&&check(words[i],0,words[i].length()-1))
{
temp.clear();
temp.push_back(empty);
temp.push_back(i);
ans1.push_back(temp);
temp.clear();
temp.push_back(i);
temp.push_back(empty);
ans1.push_back(temp);
}
}
}
return ans1;
}