字符串str是回文的情况,假设s1+s2=str,长度分别为l1,l2
如果l1=l2,那么s1s2互为翻转
如果l1不等于l2,那么长的那部分可以拆分为短的那个的翻转+回文串
现在,对于每个字符串,枚举它的每一个前缀和后缀,判断其是不是回文,如果是,那么在剩余的字符串中找有没有它剩余部分的翻转,用哈希表存储所有字符串的翻转串
class Solution {
private:
vector<string> reverStr;
unordered_map<string, int> index;
public:
int findword(string s, int left, int right)
{
auto itr = index.find(s.substr(left, right-left+1));
return itr == index.end() ? -1 : itr->second;
}
bool check(string s, int left, int right)
{
for(int i = left, j = right; i < j; i++, j--)
{
if(s[i] != s[j]) return false;
}
return true;
}
vector<vector<int>> palindromePairs(vector<string>& words) {
int n = words.size();
//翻转字符串计入哈希表
for(int i = 0; i < n; i++)
{
reverStr.push_back(words[i]);
reverse(reverStr.back().begin(), reverStr.back().end());
}
//记录翻转字符串对应的下标
for(int i = 0; i < n; i++)
{
index.emplace(reverStr[i], i);
}
vector<vector<int>> res;
for(int i = 0; i < n; i++)
{
int m = words[i].size();
if(!m) continue;
string word = words[i];
//枚举前缀和后缀
for(int j = 0; j <= m;j++)
{
//如果word[j:]是回文, 注意""是回文
if(check(word, j, m-1))
{
//找剩余的字符串中有没有word[0:j-1]的翻转
int left = findword(word, 0, j-1);
if(left != -1 && left != i)
{
res.push_back({i, left});
}
}
//如果word[:j-1]是回文
if(j && check(word, 0, j-1))
{
//在剩余字符串中找word[j:m-1]的翻转
int right = findword(word, j, m-1);
if(right != -1 && right != i)
res.push_back({right, i});
}
}
}
return res;
}
};