题目地址:
https://leetcode.com/problems/palindrome-partitioning/
给定一个长 n n n的字符串 s s s,求出其所有的分割,使得该分割中的每个片段都是回文串。
思路是DFS。每次都从某个位置开始枚举要分割出的片段,如果该片段是回文的,说明可以考虑继续搜下去,就进入下一层枚举,直到枚举到字符串末尾。代码如下:
import java.util.ArrayList;
import java.util.List;
public class Solution {
public List<List<String>> partition(String s) {
List<List<String>> res = new ArrayList<>();
int n = s.length();
// 先用区间DP来预处理一下s的每个区间是否回文
boolean[][] isPal = new boolean[n][n];
for (int len = 1; len <= n; len++) {
for (int i = 0; i + len - 1 < n; i++) {
int j = i + len - 1;
if (len == 1) {
isPal[i][j] = true;
} else {
isPal[i][j] = s.charAt(i) == s.charAt(j) && (len == 2 || isPal[i + 1][j - 1]);
}
}
}
dfs(s, 0, new ArrayList<>(), res, isPal);
return res;
}
private void dfs(String s, int pos, List<String> cur, List<List<String>> res, boolean[][] isPal) {
if (pos == s.length()) {
res.add(new ArrayList<>(cur));
return;
}
for (int i = pos; i < s.length(); i++) {
// 发现回文,截取出来
if (isPal[pos][i]) {
cur.add(s.substring(pos, i + 1));
dfs(s, i + 1, cur, res, isPal);
// 回溯的时候恢复现场
cur.remove(cur.size() - 1);
}
}
}
}
时间复杂度 O ( n 2 n ) O(n2^n) O(n2n)(所有的切割方案是指数级别的,并且在加入答案的时候还要深拷贝一下cur),空间复杂度 O ( n 2 ) O(n^2) O(n2)。