131. 分割回文串
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例:
输入: "aab"
输出:
[
["aa","b"],
["a","a","b"]
]
方法一:动态规划 + 回溯
解题思路
看到 所有可能 四个字,就知道要使用回溯算法。此外,在回溯的过程中我们需要多次判断子串是否为回文串,可以通过预处理得到所有子串是否是回文,这里采用「动态规划」预处理。
- 动态规划预处理所有子串,
dp[i][j]
表示子串[i, j]
是否为回文串。 - 通过 递归 + 回溯 去查找所有可能的结果集。
参考代码
public List<List<String>> partition(String s) {
int n = s.length();
// 动态规划预处理
boolean[][] dp = new boolean[n][n];
for (int j = 0; j < n; j++) {
for (int i = 0; i <= j; i++) {
if (s.charAt(i) == s.charAt(j) && (j - i <= 2 || dp[i + 1][j - 1])) {
dp[i][j] = true;
}
}
}
// 递归 + 回溯 查找所有结果
List<List<String>> ans = new ArrayList<>();
backtrack(ans, new LinkedList<>(), s, dp, 0, n);
return ans;
}
public void backtrack(List<List<String>> ans, Deque<String> stack, String s, boolean[][] dp, int index, int n) {
if (index == n) {
ans.add(new ArrayList<>(stack));
return;
}
for (int i = index; i < n; i++) {
if (dp[index][i]) {
stack.offerLast(s.substring(index, i + 1));
backtrack(ans, stack, s, dp, i + 1, n);
stack.pollLast();
}
}
}