前言
我在刷卡哥的“代码随想录”,自己的总结笔记均会放在“算法刷题-代码随想录”该专栏下。
代码随想录此题链接
题目
1.切割问题(切割问题抽象成组合问题)
将切割转换成为组合,相当于先选择字符串中的第1个字符(切割出第一个字符),再选择出字符串第2个字符,(切割出第二个字符);依次类推
全局变量
//1.最终总的结果集
List<List<String>> result = new ArrayList<>();
//2.分割的当前集合
LinkedList<String> path = new LinkedList<String>();
2. 本题思路分析:
回溯三部曲:
- 参数与返回值:
- 参数:整个字符串s,以及当前字符串遍历到的下标位置startIndex。
- 返回值:void
- 终止条件:
- 当前startIndex等于s的长度。
- 将当前的path加入到result中,return结束这次递归。
- 单层循环逻辑:
- for循环从startIndex开始到s的长度结束
- 判断当前的子字符串是否为回文,若是回文字符串加入到path中;如果不是,则进行下一次遍历
- 递归,参数startIndex为i + 1
- 回溯,将path的最后一个元素除去
3. 算法实现
class Solution {
List<List<String>> result = new ArrayList<>();
LinkedList<String> path = new LinkedList<>();
public List<List<String>> partition(String s) {
backtracking(s,0);
return result;
}
public void backtracking(String s,int startIndex){//左闭右闭
if(startIndex == s.length()){
result.add(new LinkedList<>(path));
}
for(int i = startIndex;i < s.length();i++){
if(isPalindrome(s,startIndex,i)){
path.add(s.substring(startIndex,i + 1));
}else{
continue;
}
backtracking(s,i + 1);
path.removeLast();
}
}
public boolean isPalindrome(String test,int left,int right){
for(int i = left,j = right;i < j;i++,j--){
if(test.charAt(i) != test.charAt(j)){
return false;
}
}
return true;
}
}
4. 算法坑点
- 单层循环中,判断当前的子字符串是否为回文,若是回文字符串加入到path中;如果不是,则进行下一次遍历。这个对于不是回文字符串直接下一次遍历这点,刚开始没想到
if(isPalindrama(s,startIndex,i)){
path.add(s.substring(startIndex,i + 1));
}else{
continue;
}
解决办法:
可以画一棵树去体会下,如果当前的子字符串不为回文字符串,那么接下去的切割毫无意义,所以应该结束这次的递归,尝试下一次遍历。