题目解读:此题目是一道经典的考验回溯方面知识的算法题,意在让我们递归得到子串的同时,去筛选出回文序列,添加到List下,最后返回。
题目思路:正如我们初步对题目解读的那样,我们需要做到以下几点:
- 递归字符串
- 筛选回文序列
第一步:
我们递归字符串的方法是这样的,假设我们有一个字符串 str = abcbaa
现在我们要找出其中的回文子串。
我的思路是这样的:对str进行一个循环+切割,比如第一次进入循环,我们就会切割为a bcbaa,第二次,我们就会切割为 ab cbaa,第三次就会切割为 abc baa…
可见,我们的切割,让字符串变成了左右两个部分,现在我们要递归的是右面的部分。
但是我们也不是傻递归,傻循环,而是有一定剪枝技巧的。就比如说,我们要求切割成最后的list,是要求里面每一个属性都为回文序列,于是我们就可以排除掉左边不是回文序列的情况,也就是做一个优化。
而在我们递归字符串的右面部分的时候,也是同样,边递归,边判断,但是区别在于,我们递归之后,要将右面再次切割好的字符串去进行遍历,判断是否满足所说的回文字符串。
第二步:
接下来就是筛选回文串了,这个其实比较简单,用暴力就可以,头尾指针遍历一下就行了。
第三步
List.add()
然后附上代码
class Solution {
public List<List<String>> partition(String s) {
return addList(s, 0);
}
private List<List<String>> addList(String s, int index) {
//出口
if (index == s.length()) {
List<String> list = new ArrayList<>();
List<List<String>> list1 = new ArrayList<>();
list1.add(list);
return list1;
}
List<List<String>> list1 = new ArrayList<>();
for (int i = index; i < s.length(); i++) {
if (isRollBack(s.substring(index, i + 1))) {
String substring = s.substring(index, i + 1);
for (List<String> l : addList(s, i + 1)) {
l.add(0, substring);
list1.add(l);
}
}
}
return list1;
}
private boolean isRollBack(String s) {
int i = 0;
int j = s.length() - 1;
while (i < j) {
if (s.charAt(i) != s.charAt(j)) {
return false;
}
i++;
j--;
}
return true;
}
}