leetcode_131. 分割回文串

给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。

返回 s 所有可能的分割方案。

示例:

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

解析:遇到这种需要返回所有可能方案的题目,应该思考是否可以用回溯法解决。
本题采用回溯法加剪枝来解决。
见图
在这里插入图片描述对于字符串aab,我们尝试在它的每一位进行截断,并对截下来的前半段进行判定,如果前半段是回文串,则将其记录,并将剩下的后半段递归调用函数,直到字符串为空。
而如果前半段不是回文串,则直接剪枝跳过。

在整个过程中,存在需要多次判定同一部分是否为回文串的可能
为了减少重复计算耗时,在回溯之前,使用动态规划的方法先行计算出每一段是否为回文串。

定义二维数组dp[s.size()][s.size()]
对于dp[i][j]表示字符串从第i个字符到第j个字符这一段是否为回文串
列出状态转移方程
dp[i][j] = (s[i]==s[j]) && (r-l<=2||dp[i+1][j-1])

下面是完整代码

class Solution {
public:
    
    vector<vector<string>> partition(string s) {
        vector<vector<char>> dp(s.size(),vector<char>(s.size(),0));
        for(int r=0;r<s.size();++r){
            for(int l=0;l<=r;++l){
                if(s[l]==s[r] && (r-l<=2||dp[l+1][r-1])) dp[l][r]=1;
            }
        }
        vector<vector<string>> res;
        vector<string> tmp;
        backtrace(dp,res,tmp,s,0);
        return res;
    }
    void backtrace(vector<vector<char>> &dp,vector<vector<string>> &res,vector<string> &tmp,string &s,int now){
        if(now>=s.size()) return res.push_back(tmp);
        for(int i=now;i<s.size();++i){
            if(!dp[now][i]) continue;
            tmp.push_back(s.substr(now,i-now+1));
            backtrace(dp,res,tmp,s,i+1);
            tmp.pop_back();
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值