将一个字符串分割成由回文串组成。
动态规划先判断出从i到j是回文的情况。
在dfs判断出所有情况。
class Solution {
public List<List<String>> partition(String s) {
int length = s.length();
ArrayList<List<String>> result = new ArrayList<>();
boolean[][] dp = new boolean[length][length];
//首先定义一个二维数组,用来存放字符串第i个位置到第j给位置是否为回文串
//回文串的条件i == j || s[i] == s[j] && s[i+1] == s[j-1]
//这里从列开始遍历
for(int j = 0; j < length; j++){
for(int i = 0; i < length; i++){
if(i == j)
dp[i][j] = true;
else {
//既然是i 到 j,那么 i 必须小于 j. i + 1 > j - 1是两个数字挨着,两个数字挨着那么并且相等必然回文
if (s.charAt(i) == s.charAt(j) && (i + 1 > j - 1 || dp[i + 1][j - 1]))
dp[i][j] = true;
}
}
}
ArrayList<String> temp = new ArrayList<>();
dfs(s,dp,result,temp,length,0);
return result;
}
private void dfs(String s,boolean[][] dp, ArrayList<List<String>> result, List<String> temp, int length,int index) {
//因为是分割字符串,所以当index到达终点,说明字符串已经分割完,返回
if (index == length){
result.add(new ArrayList<>(temp));
return;
}
//没有达到终点就递归
for(int i = index; i < length; i++){
//在i行查找可以构成回文的字符串
//index就是当前行
if (!dp[index][i]) continue;
temp.add(s.substring(index,i + 1));
//在i列构成回文,那么下一次递归就去i + 1行查找
dfs(s,dp,result,temp,length,i + 1);
temp.remove(temp.size() - 1);
}
}
}