Palindrome Partitioning II 108

Question

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.

Solution

两次动态规划。第一次动态规划palindrome[i][j],表示s中i~j的字符串是否是回文串。第二次动态规划根据palindrome求出cut[i],即前i个字符最少要切几次才能将字符串切为回文串。

palindrome:

初始化:

palindrome[i][i]=true,palindrome[i][i+1] = (s.charAt(i) == s.charAt(i+1))

即初始化一个字符和两个字符的字符串。

状态函数:palindrome[i][j] = s.charAt(i) == s.charAt(j) && palindrome[i+1][j-1],即两头字符要相等,同时中间字符串也要为回文串。

cut:

初始化:cut[i]=i-1,即前i个元素至多需要切i-1次,这里特别要注意cut[0]=-1,这是为了后面状态函数中j=0时能够满足题意。

状态函数:cut[i]=min(cut[i], cut[j]+1),即在i之前的位置上找一个切割点j,使得j~i的字符串为回文串(palindrome[j][i-1]=true),这样将前i个字符串切成回文串需要的次数为将前j个字符串切成回文串需要的最小次数+1(1表示切j的这一次),取不同j情况下的最小值即可。注意,i(前i个字符)和i-1(第i-1个字符)的含义和转换。

代码如下:

public class Solution {
    /**
     * @param s a string
     * @return an integer
     */
    private boolean[][] isPalindrome(String s){
        int m = s.length();
        boolean[][] result = new boolean[m][m];

        for(int i = 0; i < m; i++){
            result[i][i] = true;
        }

        for(int i = 0; i < m - 1; i++){
            result[i][i + 1] = (s.charAt(i) == s.charAt(i + 1));
        }

        for(int i = 2; i < m; i++){
            for(int j = 0; j < i - 1; j++){
                if(s.charAt(j) == s.charAt(i) && result[j + 1][i - 1]){
                    result[j][i] = true;
                }
            }
        }

        return result;
    }

    public int minCut(String s) {
        // write your code here
        if(s == null || s.length() == 0){
            return 0;
        }

        int n = s.length();
        int[] cut = new int[n + 1];
        boolean[][] palindrome = isPalindrome(s); 

        for(int i = 0; i <= n; i++){
            cut[i] = i - 1;
        }

        for(int i = 1; i <= n; i++){
            for(int j = 0; j < i; j++){
                if(palindrome[j][i - 1]){
                    cut[i] = Math.min(cut[i], cut[j] + 1);
                }
            }
        }

        return cut[n];
    }
};

results matching ""

    No results matching ""