132. Palindrome Partitioning II

一、题目

  1、审题

  2、分析

    给出一个字符串,将其切割后分成的子串全为回文,求最少切几刀。

二、解答

  1、思路: 

    方法一

      采用一个 DP 数组记录。

      DP[i]:表示到达下标 i 需要切的刀数。

    public int minCut2(String s) {
        
        int n = s.length();
        if (s == null || n <= 1) {
            return 0;
        }
        
        int[] dp = new int[n];
        for (int i = 0; i < n; i++) 
            dp[i] = i;
        
        for (int i = 0; i < n; i++) {
            
            // CASE 1. odd len: center is at index i, expand on both sides
            for(int start = i, end = i; start >= 0 && end < n && s.charAt(start) == s.charAt(end); start--, end++) {
                int newCutAtEnd = (start == 0) ? 0 : dp[start - 1] + 1;    // start == 0,则 第一步就能到 end
                dp[end] = Math.min(dp[end], newCutAtEnd); 
            }
            
            // CASE 2: even len: center is between [i-1, i], expand on both sides
            for(int start = i - 1, end = i; start >= 0 && end < n && s.charAt(start) == s.charAt(end); start--, end++) {
                int newCutAtEnd = (start == 0) ? 0 : dp[start - 1] + 1;
                dp[end] = Math.min(dp[end], newCutAtEnd);
            }
        }
        
        return dp[n - 1];
    }
    

    方法二:

    采用两个动态数组。

    pal[j][i] = true: 从下标 j 到下标 i 是回文。

    cut[i] = n: 到达下标 i 至少需要切 n 刀。

public int minCut(String s) {
        char[] c = s.toCharArray();
        int n = c.length;
        int[] cut = new int[n];
        boolean[][] pal = new boolean[n][n];
        
        for (int i = 0; i < n; i++) {
            int min = i;
            for (int j = 0; j <= i; j++) {
                if(c[j] == c[i] && (i - j <= 2 || pal[j+1][i-1])) {
                    pal[j][i] = true; // 从 j 到 i
                    min = (j == 0) ? 0 : Math.min(min, cut[j-1] + 1);
                }
            }
            cut[i] = min;
        }
        return cut[n - 1];
    }
原文地址:https://www.cnblogs.com/skillking/p/9759906.html