题目描述
给定一个字符串 s ,请将 s 分割成一些子串,使每个子串都是 回文串 ,返回 s 所有可能的分割方案。
回文串 是正着读和反着读都一样的字符串。
示例1
输入:s = “google”
输出:[[“g”,“o”,“o”,“g”,“l”,“e”],[“g”,“oo”,“g”,“l”,“e”],[“goog”,“l”,“e”]]
示例2
输入:s = “aab”
输出:[[“a”,“a”,“b”],[“aa”,“b”]]
示例3
输入:s = “a”
输出:[[“a”]]
思路
假设我们从start位开始分割(前面的几位已经分割完毕),如果后面还有n位(包括start自己),那么我们就会有n种情况,即只分割start自己、分割start和start+1,…,分割start~start+n(当然分割的前提是它是回文字符串)。
那么我们分割到start + ?位之后,就可以继续递归调用函数分割start+?之后的字符串。
代码
class Solution {
public String[][] partition(String s) {
List<List<String>> result = new LinkedList();
dfs(s, 0, new LinkedList(), result);
String[][] res = new String[result.size()][];
int i = 0;
for(List<String> subset : result){
int j = 0;
res[i] = new String[subset.size()];
for(String str : subset){
res[i][j++] = str;
}
i++;
}
return res;
}
private void dfs(String s, int start, LinkedList<String> subset, List<List<String>> result){
if(start == s.length()){
result.add(new LinkedList(subset));
return;
}
for(int i = start; i < s.length(); i++){
if(isPalindrome(s, start, i)){
subset.add(s.substring(start, i + 1));
dfs(s, i + 1, subset, result);
subset.removeLast();
}
}
}
private boolean isPalindrome(String s, int start, int end){
while(start < end){
if(s.charAt(start++) != s.charAt(end--)){
return false;
}
}
return true;
}
}