leetcode 131. 分割回文串 思考分析

136 阅读1分钟

题目

给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
在这里插入图片描述

思考

问题可以分为两个子问题:1、判断回文串2、分割数组

判断回文串

bool isPalindrome_string(string s,int startindex,int endindex)
{
    for(int i = startindex,j = endindex;i<j;i++,j--)
    {
        if(s[i] != s[j]) return false;
    }
    return true;
}

利用回溯法分割

回溯法分割数组和回溯法求组合的方法类似:

组合问题:选取一个a之后,在bcdef中再去选取第二个,选取b之后在cdef中在选取第三个…。
切割问题:切割一个a之后,在bcdef中再去切割第二段,切割b之后在cdef中在切割第三段…。
在这里插入图片描述
回溯的参数与返回值

//全局变量
vector<vector<string>> result;
vector<string> res;
//递归函数
void backtracking(string s,int startindex)

回溯的终止条件
当我们的startindex刚好超过了string 的范围时,说明已经切割完成了,此时将res(各个回文子串)送入result

if(startindex>=s.size())
{
	result.push_back(res);
	return;
}

回溯的逻辑
对于每一层来说,有一个startindex,从startindex到i检查是否是回文串,如果是那么将这个区间的回文字符放入子结果中,并且以这个区间的右边的一个元素开始,进入下一层的检查。如果在这个区间的字符不是回文字符串,那么跳过这个区间不进行处理。
需要注意的地方:
1、对于切割过的位置,不能重复切割。
2、substr函数的使用方法
3、单个元素也可以是回文子串,所以子串区间:[startindex,i]

for(int i=startindex;i<s.size();i++)
{
    //子串区间:[startindex,i]
    if(isPalindrome_string(s,startindex,i) == true)
    {
        //substr切割s,第一个参数是起始位置,第二个参数是切割长度
        string Palindrome_string = s.substr(startindex, i - startindex + 1);
        res.push_back(Palindrome_string);
    }
    else continue;
    //如果是回文子串,则进入下一层,如果不是,仍在这一层继续寻找回文串
    //递归,探索下一层,切割过的位置,不能重复切割
    backtracking(s,i+1);		
    //回溯,撤销处理结果
    res.pop_back();
}

代码

class Solution {
public:
    //全局变量
    vector<vector<string>> result;
    vector<string> res;
    bool isPalindrome_string(string s,int startindex,int endindex)
    {
        for(int i = startindex,j = endindex;i<j;i++,j--)
        {
            if(s[i] != s[j]) return false;
        }
        return true;
    }
    //递归函数
    void backtracking(string s,int startindex)
    {
        if(startindex>=s.size())
        {
            result.push_back(res);
            return;
        }
        for(int i=startindex;i<s.size();i++)
        {
            //子串区间:[startindex,i]
            if(isPalindrome_string(s,startindex,i) == true)
            {
                //substr切割s,第一个参数是起始位置,第二个参数是切割长度
                string Palindrome_string = s.substr(startindex, i - startindex + 1);
                res.push_back(Palindrome_string);
            }
            else continue;
            //如果是回文子串,则进入下一层,如果不是,仍在这一层继续寻找回文串
            //递归,探索下一层,切割过的位置,不能重复切割
            backtracking(s,i+1);		
            //回溯,撤销处理结果
            res.pop_back();
        }
    }
    vector<vector<string>> partition(string s) {
        result.clear();
        res.clear();
        backtracking(s,0);
        return result;
    }
};