1745. Palindrome Partitioning IV (迴文樹)

題目

題意:判斷一個字符串是否可以由三個迴文串組成
題解:利用強大的迴文樹,計算出以每個字符爲結尾的迴文串,然後從字符串的最後一個字符開始,遞歸判斷。

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);
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章