目录
一、回溯算法基础知识
二、分割回文串思路
2.1 如何切割
2.2 判断回文
2.3 回溯三部曲
2.4 其他问题
三、相关算法题目
四、总结
一、回溯算法基础知识
详见:代码随想录刷题day46|(回溯算法篇)77.组合-CSDN博客
二、分割回文串思路
回溯递归法
两个问题:1.如何切割?2.判断回文?
2.1 如何切割
切割问题可以抽象成组合问题:取自代码随想录
如何模拟切割线
切割线通过startIndex和 i 来模拟,表示当前处理的子串范围;
2.2 判断回文
利用双指针法,一个从前往后遍历字符串s,另一个从后往前遍历字符串s,当两者不等时,不是回文,返回false;否则返回true;
2.3 回溯三部曲
①函数参数和返回值:返回为空void,参数传入字符串s,以及每次递归遍历时的起始位置startIndex;
②终止条件:递归的深度,树的深度,何时结束递归:当切割到字符串的最后位置(s.length的位置)时,说明本次递归结束,将本次结果加入result结果集中,然后返回;
③单层递归逻辑:for循环中,startIndex 表示每次递归中开始遍历的起始位置,i 从startIndex开始,逐渐+1,那么[startIndex, i] 就是要截取的子串;得到子串以后,首先判断是否为回文,如果是,加入单个结果集 list 中,然后回退;如果不是,跳过本次循环,i++;
注意切割过的位置不能重复切割,所以递归中startIndex参数要传入 i+1;
2.4 其他问题
递归循环中如何截取子串?
通过String的substring方法👇
public String substring(int beginIndex, int endIndex)
返回一个新字符串,它是此字符串的一个子字符串。该子字符串从指定的 beginIndex
处开始,直到索引 endIndex - 1
处的字符。因此,该子字符串的长度为 endIndex-beginIndex
。
参数:beginIndex
- 起始索引(包括);endIndex
- 结束索引(不包括)。
示例:
"hamburger".substring(4, 8) returns "urge"
"smiles".substring(1, 5) returns "mile"
三、相关算法题目
131.分割回文串
class Solution {List<String> list = new ArrayList<>();//存放单个结果List<List<String>> result = new ArrayList<>();//存放结果集合public List<List<String>> partition(String s) {backtracking(s,0);return result;}private void backtracking(String s, int startIndex){//如果起始索引已经超过子串长度 说明分割完毕 得到结果if(startIndex >= s.length()){result.add(new ArrayList<>(list));return;}//单层递归逻辑for(int i = startIndex;i < s.length();i++){//提取从startIndex 到 i 的子串String substring = s.substring(startIndex, i + 1);//判断是否为回文if(isPalindrome(substring)){//是回文list.add(substring);backtracking(s, i+1);//递归处理剩余部分list.removeLast();//回溯 移除当前子串}}}//判断一个字符串是否是回文private boolean isPalindrome(String s){int left = 0;int right = s.length() - 1;while(left < right){if(s.charAt(left) != s.charAt(right)){return false;}left++;right--;}return true;}
}
四、总结
1.本题难点:理解分割回文串 类似 组合问题,也可以抽象成树的结构,深度代表递归的深度,宽度代表for循环;
2.切割的方式,也就是具体的树结构是什么样的?每一个节点;
3.终止条件,最后的叶子节点;
4.单层递归逻辑,每次截取的子串是哪里到哪里?
5.如何判断一个字符串是否为回文;
6.如何截取子串;
7.这真的是中等题目吗,自己想从一开始分割方式抽象成树结构就错咯😶