https://leetcode-cn.com/problems/palindrome-partitioning/

    Stri , L~R范围上能分解出多少种

    image.png

    image.png

    枚举所有前缀是回文的

    来看一下复杂度
    image.png
    枚举所有前缀 —-》 O(N),
    然后每个后面还要去递归,
    现在总的调度已经是O(N^2)了,
    然后我们还要检查是不是回文串,
    我们想不要遍历就能检查,
    能不能做个预处理结构出来?把查回文的代价减下来。
    在L~R范围上做个预处理结构出来,让我能很快地查在这个范围内的是不是回文串

    image.png

    来举个具体的例子
    dp[i][j]的含义: str 中i~j范围是不是回文
    先把两条对角线填好,
    image.png
    填普遍格子的时候,每个格子只与自己左下角的格子有关
    image.png

    image.png

    这张表生成好后,

    我们可以看到,我们的每个子过程都可以用到这张表,这就是高潮点
    image.png

    1. class Solution {
    2. boolean[][] dp = null;
    3. LinkedList<String> path = new LinkedList<>();
    4. List<List<String>> ans = new ArrayList<>();
    5. public List<List<String>> partition(String s) {
    6. dp = getdp(s.toCharArray());
    7. dfs(s, 0);
    8. return ans;
    9. }
    10. public boolean[][] getdp(char[] str) {
    11. int N = str.length;
    12. boolean[][] dp = new boolean[N][N];
    13. for (int i = 0; i < N - 1; i++) {
    14. dp[i][i] = true;
    15. dp[i][i + 1] = str[i] == str[i + 1];
    16. }
    17. dp[N - 1][N - 1] = true;
    18. for (int i = N - 3; i >= 0; i--) {
    19. for (int j = i + 2; j < N; j++) {
    20. dp[i][j] = str[i] == str[j] && dp[i + 1][j - 1];
    21. }
    22. }
    23. return dp;
    24. }
    25. public void dfs(String s, int index) {
    26. if (index == s.length()) {
    27. ans.add(new ArrayList<>(path));
    28. return;
    29. }
    30. for (int end = index; end < s.length(); end++) {
    31. if (dp[index][end]) {
    32. path.addLast(s.substring(index, end + 1));
    33. dfs(s, end + 1);
    34. // 恢复现场
    35. path.pollLast();
    36. }
    37. }
    38. }
    39. }