一、题目介绍
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例:
输入: "aab"
输出:
[
["aa","b"],
["a","a","b"]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-partitioning
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、解题思路
(1)首先通过动态规划的方法,找到所有的回文子串。
(2)之后再通过深度优先的方法(DFS),从第一个字符开始划分子串,最终找到所有可能的划分情况。
三、解题代码
class Solution {
public:
int n;
vector<vector<string>> res;
vector<vector<string>> partition(string s) {
n = s.size();
vector<vector<bool>> dp(n, vector<bool>(n, false));//字符串s从i到j的子串是否为回文串
for(int i = n-1; i >= 0; --i) //i递减
{
for(int j = i; j < n; ++j) //j递增
{
if(j == i)//单个字符
dp[i][j] = true;
else if(j-1 == i) //两个字符组成的字符串
{
if(s[i] == s[j])
dp[i][j] = true;
}
else //3个或3个以上的字符组成的字符串
{
if(dp[i+1][j-1] && s[i] == s[j])
{
dp[i][j] = true;
}
}
}
}
vector<string> temp;
for(int i = 0; i < n; ++i)
{
if(dp[0][i])
dfs(temp, dp, s, 0, i); //从第一个字符开始向后取回文串进行分割
}
return res;
}
//深度搜索
void dfs(vector<string>& temp, vector<vector<bool>>& dp, string s, int i, int j)
{
temp.push_back(s.substr(i, j-i+1));
if(j == n-1) //已经划分到结尾
res.push_back(temp);
j++; //从j+1开始继续找回文串
for(int k = j; k < n; ++k)
{
if(dp[j][k])
{
dfs(temp, dp, s, j, k);
}
}
temp.pop_back(); //退出时删除本轮添加的字符串
}
};