分割得到回文子串

131. 分割回文串

 

 回溯+动态规划预处理

类似于多叉树的结构,每次分隔出一个字符串sub,如果sub是回文,那么继续分隔,如果sub不是回文,就把sub归还回去,当前的分割结果也要恢复到分割之前,重新分割。 

class Solution {
private:
    vector<vector<string>> res;
    vector<string> cur;
    int len;

    // 回溯:寻找分割方案
    void dfs(string &s, int idx, vector<vector<bool>>& dp){    // 采用引用传递,节省空间和复制时间
        if(idx==len){
            res.push_back(cur);
            return;
        }
        for(int i=idx;i<len;i++){
            if(dp[idx][i]){
                cur.push_back(s.substr(idx, i-idx+1));
                dfs(s, i+1, dp);
                cur.pop_back();    // pop_back()删除vector的最后一个元素,vector长度-1
            }
        }
        return;
    }
public:
    vector<vector<string>> partition(string s) {
        len = s.length();
        if(len==1){
            res.push_back({s});
            return res;
        }

        // 动态规划预处理寻找[j, i]区间内的回文字符串
        vector<vector<bool>> dp(len, vector<bool>(len, false));
        for(int i=0;i<len;i++){
            for(int j=0;j<=i;j++){
                if(s[i]==s[j] && (i-j<=2 || dp[j+1][i-1])){
                    dp[j][i] = true;
                }
            }
        }
        dfs(s, 0, dp);
        return res;
    }
};   

 

 回溯问题的理解:是一种借助递归的暴力搜索,判断每个可能分支,通过加入约束条件来剪枝(不满足的选择分支无需继续计算下去),可以考虑用树形结构来表示所有可能结果。

根节点:开始节点,往往是全体数据;

叶子节点:当前解空间正确的最后结果;

从根节点出发,按照要求做出各种选择,如果其中一个选择满足约束条件,继续计算下去,直到找到叶子节点,这一条从根节点到叶子节点的路径即为一个正确的解。

记忆回溯是每次计算时都记录中间结果,无论是否回溯,都可以辅助判断选择是否正确。

选择、约束条件、目标

模板:

1、for循环列举当前的所有选择;

2、判断当前选择是否正确,如果正确,在这个选择基础上继续递归,可能需要记录当前的结果substr等;如果选择不正确,递归结束;

5、撤销当前结果,判断下一个选择。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值