131. 分割回文串 - leetcode刷题(C++)

一、题目

131. 分割回文串

二、分析

  1. 看到所有可能的***,一般都采用递归+回溯。
  2. 首先画出来分析树,因为是将 s 分割成一些子串,所以可以按照每次划分几个字符为树节点分叉。图中的-代表划分的分界线。
    可以看到需要维护一个vector: path来记录每一步已经划分完的、且为回文串的子串,请仔细阅读这句话。还需要维护一个划分起始点startCut
    在这里插入图片描述
  3. 根据上图,可以知道当划分起始点为原字符串长度时,终止递归,将path拷贝到result中。所以有了以下代码:
 if(startCut == len){
     result.push_back(path);
	 return;
}
  1. 每进入一个树结点的子节点,都要判断即将划分的子串是否是回文串,如果不是,直接跳过,比如图中的a - ab -
    判断子串是否为回文串的函数就不单独写了。
  2. 从第一层可以看到,有了划分起始点startCut之后,每次需要截取多长的子串,是需要遍历的。(例如,startCut = 0时,分别截取1、2、3个字符)所以需要加一个for循环。
子树第一层:startCut = 0: 截取1, 2, 3. 对应了根节点的3个分支
子树第二层:startCut = 1: 截取1, 2. 对应了最左侧子树的两个分支
子树第三层:startCut = 2: 截取1

----- 代码:

for(int i = startCut; i < len; i ++){
	// 截取子串 startCut 开始的 i-startCut + 1个字符。
    string substr = s.substr(startCut,i-startCut+1);
     if(substr == "" || !isnotH(substr)) continue;

    path.push_back(substr);
    // 每次截取之后,都要从截取到的地方作为新的 划分起始点。比如从0开始截了2字符,那下次的startCut就是2。
    DFSback(s, len, 1 + i);
    path.pop_back();
}

三、代码

class Solution {
private:
    vector<vector<string>> result;
    vector<string> path;
public:
    vector<vector<string>> partition(string s) {
        
        DFSback(s, s.length(), 0);
        return result;
    }
    // 回溯
    void DFSback(string s, int len, int startCut){
        if(startCut == len){
        	// 终止递归
            result.push_back(path);
            return;
        }

        for(int i = startCut; i < len; i ++){
            string substr = s.substr(startCut,i-startCut+1);
            if(substr == "" || !isnotH(substr)) continue;

            path.push_back(substr);
            DFSback(s, len, 1 + i);
            path.pop_back();
        }
    }
    // 是否为回文串
    bool isnotH(string str){
        if(str.length() == 1) return true;
        for(int i = 0; i < str.length()/2; i ++){
            if(str[i] != str[str.length() - i - 1]) return false;
        }
        return true;
    }
};

执行用时:192 ms, 在所有 C++ 提交中击败了48.77%的用户
内存消耗:78 MB, 在所有 C++ 提交中击败了32.18%的用户

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值