[leetCode]131. 分割回文串
题目
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例:
输入: "aab"
输出:
[
["aa","b"],
["a","a","b"]
]
回溯
字符串的分割问题可以抽象成组合问题, 例如字符串abcdef:
- 组合问题:
先取一个字符a,再从bcdef取第二个,选取b后再从cdef取第三个。。。。 - 分割问题:
分割字符a后,在bcdef中分割第二段,选取b后在cdef中分割第三段。。。
- 确定回溯参数
第一个参数为切割的字符串,第二个参数为切割的起始位置(已经切割过的位置不能再切割) - 确定退出条件
当切割起始位置startIndex >= s.length()
时说明整个字符串切割完毕,将答案加入结果集合 - 单层逻辑
判断当前切割范围是否为回文串,如果不是则跳过,如果是则将切割后的子串加入集合中,然后进行递归,切割的起始位置+1。回到上一层后要进行回溯。
class Solution {
// 存放结果集
private List<List<String>> result = new ArrayList<>();
// 存放结果
private List<String> path = new ArrayList<>();
public List<List<String>> partition(String s) {
backTracking(s, 0);
return result;
}
// startIndex 控制切割的起点
private void backTracking(String s, int startIndex) {
if (startIndex >= s.length()) {
result.add(new ArrayList<>(path));
return;
}
for (int i = startIndex; i < s.length(); i++) {
if (isPalindrome(s, startIndex, i)) {
String subStr = s.substring(startIndex, i + 1);
path.add(subStr);
} else {
continue;
}
backTracking(s, i + 1);
path.remove(path.size() - 1);
}
}
// 判断字符串s在[start,end] 范围内是否是回文串
private boolean isPalindrome(String s, int start, int end) {
char[] chars = s.toCharArray();
while (start <= end) {
if (chars[start] != chars[end]) {
return false;
}
start++;
end--;
}
return true;
}
}