[LintCode] Palindrome Partitioning II

344 查看

Problem

Given a string s, cut s into some substrings such that every substring is a palindrome.

Return the minimum cuts needed for a palindrome partitioning of s.

Example

Given s = "aab",

Return 1 since the palindrome partitioning ["aa", "b"] could be produced using 1 cut.

Note

回文串的题目都是好题。Palindrome Partitioning I是DFS的做法,II是DP的做法。所以不放在一篇文章里讨论。
本题的思路是:建立boolean二维数组dp[i][j],存放字符串s从第i到第j位是否为回文的布尔值;同时建立整型数组min[i],存放从最后一位到第i位都是回文串的最小切割次数。然后从字符串s的最后一个字符开始,向前进行分析。
举个例子。假设我们从后向前,分析到第i位,开始判断dp[i][j],若为true,说明从第j位向前到第i位的子串是一个回文串,则min[i]就等于第j位的结果min[j]1。然后让j继续增大,判断第i位到最后一位的范围内,有没有更长的回文串,更长的回文串意味着存在更小的min[j],用新的min[j]+1来替换min[i]

Solution

public class Solution {
    public int minCut(String s) {
        int n = s.length();
        boolean[][] dp = new boolean[n][n];
        int[] min = new int[n];
        for (int i = n-1; i >= 0; i--) {
            min[i] = n-i-1;
            for (int j = i; j < n; j++) {
                dp[i][j] = s.charAt(i) == s.charAt(j) && (dp[i+1][j-1] || j-i <= 1);
                if (dp[i][j]) min[i] = Math.min(min[i], j+1 < n ? min[j+1]+1 : 0);
            }
        }
        return min[0];
    }
};