下面是题目链接:
https://leetcode-cn.com/problems/palindrome-partitioning/
131.分割回文串
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例: 输入: "aab" 输出: [ ["aa","b"], ["a","a","b"] ]
这道题和组合题有异曲同工之妙,组合是选中2个数,这道题是选中的2个数作为区间的始终判断这个区间是否为回文,解题方面也和组合的回溯差不多。还是套用递归四部曲:
递归作用:讨论s中所有以为startIndex开始取的子串是否回文
递归参数:s是要分割的字符串,startIndex是这一层分割子串的起点
终止条件:startIndex >= s.length
单层逻辑:for循环遍历startIndex之后的所有元素作为终点的情况,如果i可以作为终点,那么就再探讨以i+1作为起点的情况,就在这一步实现分割。定义分割前的状态为初始状态
//这是回溯算法,所以在本层操作完后要记得初始化状态量回溯
class Solution {
List<List<String>> result = null;//存放最后的结果
List<String> path = null;//存放目前收集到的回文串
void partition1(String s, int startIndex){
//递归作用:讨论s中所有以为startIndex开始取的子串是否回文
//递归参数:s是要分割的字符串,startIndex是这一层分割子串的起点
//终止条件:startIndex >= s.length
//单层逻辑:for循环遍历startIndex之后的所有元素作为终点的情况,如果i可以作为终点,那么就再探讨以i+1作为起点的情况,就在这一步实现分割。定义分割前的状态为初始状态
if(startIndex >= s.length()) {
result.add(new ArrayList(path));
return;
}
for(int i = startIndex; i < s.length(); i++){//从startIndex开始取终点
if(isValid(s, startIndex, i)){//判断[startIndex,i]区间的子串是否回文
//添加回文子串
path.add(s.substring(startIndex, i + 1));
partition1(s, i + 1);//以i+1为起点开始判断新的回文子串
//删除这一层添加的回文子串回溯
path.remove(path.size() - 1);
}//如果以i为终点不行的话,直接在for里取下一位为终点进行尝试
}
}
boolean isValid(String s, int begin, int end){//判断[begin,end]是否为回文
for(int i = begin, j = end; i <= j; i++, j--)
if(s.charAt(i) != s.charAt(j))
return false;
return true;
}
public List<List<String>> partition(String s) {
result = new ArrayList<>();
path = new ArrayList<>();
partition1(s, 0);
return result;
}
}