题意:判断一个字符串是否可以由三个回文串组成
题解:利用强大的回文树,计算出以每个字符为结尾的回文串,然后从字符串的最后一个字符开始,递归判断。
struct Tree
{
int next[4005][30];
int fail[4005];
int cnt[4005];
int num[4005];
int len[4005];
int s[4005];
int p;
int n;
int last;
int new_node(int x)
{
memset(next[p], 0, sizeof(next[p]));
len[p] = x;
num[p] = 0;
cnt[p] = 0;
return p++;
}
void init()
{
p = 0;
new_node(0);
new_node(-1);
n = 0;
last = 0;
fail[0] = 1;
s[0] = -1;
}
int get_fail(int x)
{
while (s[n - len[x] - 1] != s[n])
x = fail[x];
return x;
}
int add(int x)
{
x -= 'a';
s[++n] = x;
int cur = get_fail(last);
if (!(last = next[cur][x]))
{
int now = new_node(len[cur] + 2);
fail[now] = next[get_fail(fail[cur])][x];
next[cur][x] = now;
num[now] = num[fail[now]] + 1;
cnt[now]++;
last = now;
return 1;
}
cnt[last]++;
return 0;
}
void count()
{
for (int i = p - 1; i >= 0; i--)
{
cnt[fail[i]] += cnt[i];
}
}
};
class Solution {
public:
vector<vector<int>> num;
bool fun(int x, int y)
{
if(x < 0 && y < 3)
{
return false;
}
if (y == 3)
{
if (x == -1)
return true;
return false;
}
for (int i = 0; i < num[x].size(); i++)
{
if(fun(num[x][i] - 1, y + 1))
return true;
}
return false;
}
bool checkPartitioning(string s) {
Tree tree = Tree();
tree.init();
for (int i = 0; i < s.length(); i++)
{
tree.add(s[i]);
vector<int> m;
int x = tree.last;
m.push_back(i - tree.len[x] + 1);
while (tree.fail[x] > 0)
{
x = tree.fail[x];
m.push_back(i - tree.len[x] + 1);
}
num.push_back(m);
}
return fun(s.length() - 1, 0);
}
};