[leetcode] Palindrome Partitioning II

Given a string s, partition s such that every substring of the partition is a palindrome.

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

For example, given s = "aab",
Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.

https://oj.leetcode.com/problems/palindrome-partitioning-ii/

 

思路:DP。cuts[i]表示从i到结尾的子串,要达到题意需要的最少切割数。isPalin用来判断是否是palindrome。

  初始化:cuts[i]=len-i

  推倒:cuts[i]=true   if   s.charAt(i) == s.charAt(j) && (j - i < 2 || isPalin[i + 1][j - 1])

  推倒的同时求出isPalin数组的值,提高效率。

 

public class Solution {
    public int minCut(String s) {
        if (s == null || s.length() == 0)
            return 0;
        int len = s.length();
        boolean[][] isPalin = new boolean[len][len];
        int[] cuts = new int[len + 1];
        for (int i = 0; i < len; i++)
            cuts[i] = len - i;

        for (int i = len - 1; i >= 0; i--) {
            for (int j = i; j < len; j++) {
                if (s.charAt(i) == s.charAt(j) && (j - i < 2 || isPalin[i + 1][j - 1])) {
                    isPalin[i][j] = true;
                    cuts[i] = Math.min(cuts[i], cuts[j + 1] + 1);
                }
            }

        }

        return cuts[0] - 1;

    }

    public static void main(String[] args) {
        System.out.println(new Solution().minCut("bb"));
    }
}

 

第二遍记录:注意DP的出事状态和递推关系,与第一遍解法不同,dp[i]代表s[0..i]的最小分割数,需要根据当前元素是否与之前元素组成回文不断更新最小值。

    public int minCut(String s) {
        if (s == null || s.length() == 0)
            return 0;
        int len = s.length();
        boolean[][] isPalin = new boolean[len][len];
        int[] cuts = new int[len + 1];
        for (int i = 0; i <= len; i++)
            cuts[i] = i;

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

        }

        for (int i = 1; i <= len; i++) {for (int j = 1; j <= i; j++) {
                if (isPalin[j - 1][i - 1]) {
                    cuts[i] = Math.min(cuts[i], cuts[j - 1] + 1);
                }
            }

        }

        return cuts[len] - 1;

    }

 

 

第三遍记录:

  dp[i]代表s[0..i]的最小分割数

  注意dp数组初始状态

  先用二位dp求出isPalin数组用于后面快速查询

/**
 * 
s: abaab
minCut:2

     ""  a    b    a    a    b    b
dp   -1  0    1    0    1    2    2
init -1  0    1    2    3    4    5 

 *
 */

public class Solution {
    public int minCut(String s) {
        if (s == null || s.length() <= 1)
            return 0;
        int n = s.length();
        int[] dp = new int[n + 1];
        for (int i = 0; i <= n; i++)
            dp[i] = i - 1;

        boolean[][] isPalin = new boolean[n][n];
        for (int i = n - 1; i >= 0; i--) {
            for (int j = i; j < n; j++) {
                if (s.charAt(i) == s.charAt(j) && (j - i < 2 || isPalin[i + 1][j - 1])) {
                    isPalin[i][j] = true;
                }
            }

        }

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

        return dp[n];

    }

    public static void main(String[] args) {
        System.out.println(new Solution().minCut("abababab"));
    }
}

 

 

参考:

http://blog.csdn.net/worldwindjp/article/details/22066307

http://www.tuicool.com/articles/jmQ3uu

posted @ 2014-07-06 23:10  jdflyfly  阅读(176)  评论(0编辑  收藏  举报