LeetCode刷题(每日一题) --131. 分割回文串(回溯+动态规划)

题目

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

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

示例:

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

解答

思路

回溯

  • 如果要找出所有的回文串,那么可以从当前的位置依次进行切分判断,之后将满足的进行归纳。但是毫无疑问,这种暴力法不提倡。
  • 对以上进行改进,如果当前的字串已经不是回文,那么在其之后的划分已经没必要,所以可以进行建筑。
  • 对每一种路径,保存当前的划分结果,当达到停止条件时,进行最后的返回

动态规划

  • 如果按照以上操作进行,那么会出现很多重复的判断,从而造成浪费。因此,可以提前初始化二维容器,将每一段字串是否为回文进行记录。当进行回溯时,提升速度。
  • 动态规划表达式,如果i=j,则表示为同一个字符,为回文;如果j-i=1,则为两个字符,需要判断是否相同;如果j-i>1,则为三个及以上字符,需要判断i+1j-1的字串是否为回文以及当前i字符j字符相同。因此,可以将后两种进行合并,最后表达式如下图。

图解

在这里插入图片描述

在这里插入图片描述

代码

class Solution {
private:
    vector<vector<int>> f;
    vector<vector<string>> ret;
    vector<string> ans;
    int n;

public:
    void dfs(const string& s,int i)//传入总的字符串,以及当前执行层数
    {
        if(i==n)   //如果已经执行到最后一个
        {
            ret.push_back(ans);     //将当前结果加入到答案容器中,并且结束
            return;
        }
        for(int j=i;j<n;++j)    //如果不是,则继续选择分支(一层中的不同分支),广度优先
        {
            if(f[i][j])     //如果当前的字串为回文,则保留结果,并且继续循环
            {
                ans.push_back(s.substr(i,j-i+1));   //保存当前的回文字传  
                dfs(s,j+1);     //继续下一层的循环查找
                ans.pop_back(); //移除,便于重新回溯
            }
        }
    }
    vector<vector<string>> partition(string s) {
        n = s.size();   //获取当前字符串的数量
        f.assign(n,vector<int>(n,true));    //赋值函数,不同容器但相容的赋值

        for(int i=n-1;i>=0;--i) //横坐标从后开始迭代
        {
            for(int j=i+1;j<n;++j)  //纵坐标从当前的前一位进行动态规划
            {
                f[i][j] = (s[i]==s[j])&&f[i+1][j-1];    
            }
        }
        dfs(s,0);
        return ret;
    }
};

知识点

回溯框架

  1. 选择
  2. 约束条件
  3. 目标格式

动态规划框架

  1. 递推式
  2. 初始条件
  3. 目标格式

assgin()函数

可以对不同容器但是样式相同进行赋值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hanzoe_lwh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值