【每日算法】LeetCode 131 —— 分割回文串(二百二十一)

题目内容

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。

回文串 是正着读和反着读都一样的字符串。

示例

示例 1:

输入:s = “aab”
输出:[[“a”,”a”,”b”],[“aa”,”b”]]

示例 2:

输入:s = “a”
输出:[[“a”]]

提示

1、1 <= s.length <= 16
2、s 仅由小写英文字母组成

题解

本题考查动态规划和搜索算法。

首先预处理一下子串是否是回文串,使用动态规划的思想。设F[i][j]代表s[i:j]是回文串,有递推关系式:

当Si==Sj 且F[i+1][j-1] = true时,F[i][j] = true,即F[i][j]是回文串。

然后,进行递归搜索,u代表处理到的当前位置,枚举全部可能的回文串,递归搜索直到处理完整个字符串。

代码

class Solution {
public:
vector<vector<bool>> f;
vector<vector<string>> ans;
vector<string> path;

vector<vector<string>> partition(string s) {
int n = s.size();
f = vector<vector<bool>>(n,vector<bool>(n));
for(int j = 0;j<n;j++){
for(int i = 0; i <= j;i++){
if(i == j) f[i][j] = true;
else if(s[i] == s[j]){
if(i+1 > j - 1 || f[i+1][j - 1] == true){
f[i][j] = true;
}
}
}
}
dfs(s, 0);

return ans;
}
void dfs(string& s,int u){
if(u == s.size()) ans.push_back(path);
else{
for(int i = 0;i < s.size();i++){
if(f[u][i]){
path.push_back(s.substr(u,i - u + 1));
dfs(s,i + 1);
path.pop_back();
}
}
}
}
};
Author: Frederic Niu
Link: https://www.fredericniu.cn/2021/08/23/【每日算法】LeetCode-131-——-分割回文串(二百二十一)/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
我的公众号