首先标记出所有的回文子串。boolean f[i][j]表示下标[i,j]构成的子串是回文串。

使用中心扩展法来算出整个f数组:枚举每一个下标为回文串的中心,然后逐渐向两边尽可能的扩展。最终O(n^2)跑完f数组。

然后使用dfs枚举出所有可能性

粗心了一下,可惜没有1A

class Solution {
    public List<List<String>> partition(String s) {
        int n = s.length();

        boolean f[][] = new boolean[n][n];
        for (int i = 0; i < n; i++) {
            f[i][i] = true;
        }

        for (int i = 0; i < n; i++) {
            int l = i - 1;
            int r = i + 1;
            while (l >= 0 && r < n) {
                if (s.charAt(l) == s.charAt(r)) {
                    f[l][r] = true;
                } else {
                    break;
                }
                l--;
                r++;
            }

            l = i;
            r = i + 1;
            while (l >= 0 && r < n) {
                if (s.charAt(l) == s.charAt(r)) {
                    f[l][r] = true;
                } else {
                    break;
                }
                l--;
                r++;
            }
        }

        List<List<String>> ans = new ArrayList<>();
        dfs(ans, new ArrayList<>(), f, 0, n, s);

        return ans;
    }

    private void dfs(List<List<String>> ans, List<String> cur, boolean f[][], int k, int n,
            String s) {
        if (k == n) {
            ans.add(cur);
            return;
        }

        for (int i = k; i < n; i++) {
            if (f[k][i]) {
                List<String> next = new ArrayList<>(cur);
                next.add(s.substring(k, i + 1));
                dfs(ans, next, f, i + 1, n, s);
            }
        }
    }
}