LeetCode: 131. Palindrome Partitioning
LeetCode: 131. Palindrome Partitioning
I’m come back ! 从今天开始,争取每天刷一道 LeetCode,并写一篇相应的题解。
题目描述
Given a string s
, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s
.
Example:
Input: "aab"
Output:
[
["aa","b"],
["a","a","b"]
]
解题思路 —— 动态规划构建回文表格, 深度优先搜索构建 palindrome partitioning
动态规划构建回文表格(bPalindromes)
利用动态规划, 将给定字符串 s
中的回文子串识别出来,具体操作如下。
1. 定义。记, bPalindromes[i][j]
为字符串 s
在区间 [i, j)
的子串为回文串的真值性。如,s = aabaa
时, bPalindromes[1][4] = true, bPalindromes[1][3] = false
。
2. 初始化。空串 bPalindromes[i][i]
和 单字符串 bPalindromes[i][i+1]
为回文串。
3. 状态转移方程。s
串在 [i, j)
区间的子串是回文串的充要条件是:s
串在 [i+1, j-1)
区间的子串是回文串, 且 s[i] == s[j-1]
。即:bPalindromes[i][j] = (bPalindromes[i+1][j-1] && s[i] == s[j-1])
。
4. 例子。 当 s = aabaa
时,
(0)s
字符串:
(1)初始化后的回文表格 bPalindromes
:
(2) 状态转移后的回文表格:
深度优先搜索构建 palindrome partitioning
根据回文表格记录的回文子串信息,深度优先搜索能拼凑出 s
串的回文子串的所有可能。
AC 代码
class Solution {
private:
// 根据待处理字符串 s 构造回文表格(bPalindromes)
void ConstructPalindromesTable(vector<vector<bool>>& bPalindromes, const string& s)
{
// initializing...
bPalindromes.resize(s.size()+1);
for(size_t i = 0; i < s.size()+1; ++i)
{
bPalindromes[i].resize(s.size()+1, false);
}
// s 串中的单个字符 [i, i+1) 一定是回文的
// 定义空串 [i, i) 也是回文的
for(size_t i = 0; i < s.size(); ++i)
{
bPalindromes[i][i+1] = true;
bPalindromes[i][i] = true;
}
for(size_t j = 1; j < s.size()+1; ++j)
{
for(size_t i = 0; i < j; ++i)
{
// [i, j) 是回文串的充要条件: [i+1, j-1) 是回文串,且 s[i] == s[j-1]
if(bPalindromes[i+1][j-1] == true && s[i] == s[j-1])
{
bPalindromes[i][j] = true;
}
}
}
}
// 根据回文表格(bPalindromes)构造 “all possible palindrome partitioning of s”
void ConstructPalindromes(const vector<vector<bool>>& bPalindromes, const string& s,
vector<vector<string>>& palindromes,
vector<string>& curPalindrome, int curState)
{
if(curState >= bPalindromes.size()-1)
{
if(!curPalindrome.empty()) palindromes.push_back(curPalindrome);
return;
}
for(int nextState = curState+1; nextState < bPalindromes.size(); ++nextState)
{
if(bPalindromes[curState][nextState] == true)
{
curPalindrome.push_back(s.substr(curState, nextState-curState));
ConstructPalindromes(bPalindromes, s, palindromes, curPalindrome, nextState);
curPalindrome.pop_back();
}
}
}
public:
vector<vector<string>> partition(string s) {
if(s.empty()) return {{}};
// bPalindromes[i][j]: s 串的 [i, j) 区间是回文
vector<vector<bool>> bPalindromes;
// 构造回文表格
ConstructPalindromesTable(bPalindromes, s);
// 构造解
vector<vector<string>> palindromes;
vector<string> curPalindrome;
ConstructPalindromes(bPalindromes, s, palindromes, curPalindrome, 0);
return palindromes;
}
};