给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。

返回 s 所有可能的分割方案。

示例:

输入: "aab"
输出:
[
["aa","b"],
["a","a","b"]
]

答案:

 1public List<List<String>> partition(String s) {
2    List<List<String>> res = new ArrayList<>();
3    boolean[][] dp = new boolean[s.length()][s.length()];
4    for (int i = 0; i < s.length(); i++) {
5        for (int j = 0; j <= i; j++) {
6            if (s.charAt(i) == s.charAt(j) && (i - j <= 2 || dp[j + 1][i - 1])) {
7                dp[j][i] = true;
8            }
9        }
10    }
11    helper(res, new ArrayList<>(), dp, s, 0);
12    return res;
13}
14
15private void helper(List<List<String>> res, List<String> path, boolean[][] dp, String s, int pos) {
16    if (pos == s.length()) {
17        res.add(new ArrayList<>(path));
18        return;
19    }
20    for (int i = pos; i < s.length(); i++) {
21        if (dp[pos][i]) {
22            path.add(s.substring(pos, i + 1));
23            helper(res, path, dp, s, i + 1);
24            path.remove(path.size() - 1);
25        }
26    }
27}

解析:
这是递归加回溯的方法,我们已经解过很多类似这种题型了,这里的二维数组dp[j][i]表示的是字符串s从位置j到i的子串是回文串。所以第21行要判断从位置pos到i是否是回文串。当然我们还可以每次截取字符串的时候在判断是否是回文串,然后再进行后续的计算

 1public List<List<String>> partition(String s) {
2    List<List<String>> res = new ArrayList<List<String>>();
3    List<String> list = new ArrayList<String>();
4    dfs(s, 0, list, res);
5    return res;
6}
7
8public void dfs(String s, int pos, List<String> list, List<List<String>> res) {
9    if (pos == s.length())
10        res.add(new ArrayList<String>(list));
11    else {
12        for (int i = pos; i < s.length(); i++) {
13            if (isPal(s, pos, i)) {
14                list.add(s.substring(pos, i + 1));
15                dfs(s, i + 1, list, res);
16                list.remove(list.size() - 1);
17            }
18        }
19    }
20}
21
22public boolean isPal(String s, int low, int high) {
23    while (low < high)
24        if (s.charAt(low++) != s.charAt(high--))
25            return false;
26    return true;
27}

写法有点区别,但解题思路还是一样的。