题目:
给定一个字符串 s
,请将 s
分割成一些子串,使每个子串都是 回文串 ,返回 s 所有可能的分割方案。
回文串 是正着读和反着读都一样的字符串。
示例 :
输入:s = "google" 输出:[["g","o","o","g","l","e"],["g","oo","g","l","e"],["goog","l","e"]]
思路:
先有回溯这个树的结构
节点表示没有并扫描到的字符,递归用来纵向遍历,for循环用来横向遍历。
复杂度:
时间:
动态规划预处理的复杂度为 O(n^2);爆搜过程中每个字符都可以作为分割点,并且有分割与不分割两种选择,方案数量为 2^{n - 1},每个字符都需要往后检查剩余字符的分割情况,复杂度为 O(n)O(n)。整体复杂度为 O(n * 2^n)
空间:O(n * 2^n)
代码:
public String[][] partition(String s) {
//已经写过很多遍了开头模板
List<List<String>> res = new ArrayList<>();
backtracking(s,0,new LinkedList<>(),res);
return res;
}
private void backtracking(String str,int start, LinkedList<String> cur,List<List<String>> res){
//终止条件
if(start==str.length()){
//添加结果
res.add(new LinkedList<String>(cur));
return;
}
//用for循环遍历
for(int i = start;i<str.length();i++){
//调用一个判断是不是回文字符串的方法
if(isPalindrome(str,start,i)){
//如果是回文就添加
cur.add(str.substring(start,i+1));
//递归
backtracking(str,i+1,cur,res);
cur.removeLast();
}
}
}
private boolean isPalindrome(String str,int start,int end){
while(start<end){
if(str.charAt(start++)!=str.charAt(end--)) return false;
}
return true;
}