码迷,mamicode.com
首页 > 其他好文 > 详细

[LintCode] Palindrome Partitioning II

时间:2015-11-11 06:21:31      阅读:344      评论:0      收藏:0      [点我收藏+]

标签:

Palindrome Partitioning II

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

For example, given s = "aab",

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

 

SOLUTION :

这个题一定要熟记,掌握,这题包含了两个DP。

首先看,这个题是问minimum cuts,自然想动归去,题目给了一个string s,先去按照一维动归考虑,先定义一个result[]存放dp结果。

考虑四大要素:

状态:f(x) = string以x位置结尾时候的最小切数。

转移方程: f (i) = min{f(i) ,f (j) + 1} && s字符串从j + 1到 第i 位也需要是回文串==> f(i) = min(f(j) + 1) && s.substring(j + 1 - 1, i - 1) is a palindrome

初始化:想一下,单个字母肯定是回文串,所以,长度为n的字符串,最多可以切成呢n-1个回文串(每个字母中间都切一下),所以就是f(i) = i - 1;并且f(0) = -1,这是保证第一个单个字母被程序认定为合法回文串的先行条件。

结果,f(s.length());

第一个dp出来了,现在看,判断回文串部分,如果不用dp的话,那么时间复杂度O(n),全部时间复杂度n的三次方,太高了。所以必须用记忆化搜索或者dp优化一下。

判断回文串DP:

状态:result[i][j] 表示从i开始到j结束的子字符串是不是回文串

转移方程:result[i][j] = result[i + 1][ j + 1] && s.charAt(i) == s.charAt(j)

初始化,上面这个是从两边,趋紧到中间的过程,所以,最后可能收拢为一个字母,或者两个字母(取决于总长度是单数还是双数)。所以初始化所有单个字母,以及子字符串长度为2的字符串

结果:返回所有result[][]

 

技术分享
public class Solution {
    /**
     * @param s a string
     * @return an integer
     */
    private boolean[][] getIsPalindrome(String s){
        boolean[][] result = new boolean[s.length()][s.length()];
        for (int i = 0; i < s.length(); i++){
            result[i][i] = true;
        }
        for (int i = 0; i < s.length() - 1; i++){
            result[i][i + 1] = (s.charAt(i) == s.charAt(i + 1));
        }
        for (int i = 2; i < s.length(); i++){
            for (int j = 0; j + i < s.length(); j++){ //j = start pos; i = substring len;
                result[j][j + i] = (result[j + 1][j + i - 1] && s.charAt(j) == s.charAt(j + i));
            }
        }
        return result;
    } 
    public int minCut(String s) {
        int[] result = new int[s.length() + 1];
        if (s == null || s.length() == 0){
            return 0;
        }
        //initial
        for (int i = 0; i <= s.length(); i++){
            result[i] = i - 1;
        }
        boolean[][] isPalindrome = getIsPalindrome(s);
        //
        for (int i = 1; i <= s.length(); i++){
            for (int j = 0; j < i; j++){
                if (isPalindrome[j][i - 1]){
                    result[i] = Math.min(result[i], result[j] + 1);
                }
            }
        }
        return result[s.length()];
    }
};
View Code

 

[LintCode] Palindrome Partitioning II

标签:

原文地址:http://www.cnblogs.com/tritritri/p/4955010.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!