• LeetCode132. 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.

    Example:

    Input: "aab"
    Output: 1
    Explanation: The palindrome partitioning ["aa","b"] could be produced using 1 cut.

    思路

    解法还是dp。

    定义函数
    D[i,n] = 区间[i,n]之间最小的cut数,n为字符串长度
     a   b   a   b   b   b   a   b   b   a   b   a
                         i                                  n
    如果现在求[i,n]之间的最优解?应该是多少?简单看一看,至少有下面一个解
     a   b   a   b   b   b   a   b   b   a   b   a
                        i                  j   j+1      n
    此时  D[i,n] = min(D[i, j] + D[j+1,n])  i<=j <n。这是个二维的函数,实际写代码时维护比较麻烦。所以要转换成一维DP。如果每次,从i往右扫描,每找到一个回文就算一次DP的话,就可以转换为
    D[i] = 区间[i,n]之间最小的cut数,n为字符串长度, 则,
    D[i] = min(1+D[j+1] )    i<=j <n

    也就是说当从i往n方向一个个切割位置去试的时候,如果左边构成了回文,那么现在只需要考虑右边的切割方法,所以是 1+D[j+1]。加1是因为我们现在切割了一次。i<=j <n,在从i往n方向一个个切割位置去的试的这个过程中,求所有的 1+D[j+1]的最小值即可。

    如何判断[i,j]是否是回文?这也是一个DP问题。

    定义函数
    P[i][j] = true if [i,j]为回文
    那么
    P[i][j] = ((str[i] == str[j]) && (P[i+1][j-1]));

    代码

    class Solution {
        public int minCut(String s){
            int len=s.length();
            int[] dp=new int[len+1];  

         for(int i=len;i>=0;i--){ dp[i]=len-i;  // 对于考虑区间[i~len],初始赋给其可能的最大分割数,也就是分解为单个字符 } boolean[][] pal=new boolean[len][len]; for(int i=len-1;i>=0;i--){ for(int j=i;j<len;j++){ // 左:s[i~j] 右:D[j+1~len] if(s.charAt(i)==s.charAt(j)&&(j-i<2 || pal[i+1][j-1])) { pal[i][j]=true; dp[i]=Math.min(dp[i],1+dp[j+1]); } } } return dp[0]-1; // 最终要求的是分割数等于分割块数减1 } }

    参考

    https://blog.csdn.net/doc_sgl/article/details/13418125

  • 相关阅读:
    【web安全】浅谈web安全之XSS
    【css】浅谈BFC
    nodejs笔记一--模块,全局process对象;
    逼真打字机效果;
    深入理解CSS3 animation的steps
    网址链接收藏
    用hoverclock插件实现HTML5时钟
    JS多种方法实现随机颜色;
    canvas实现跟随鼠标旋转的箭头
    封装insertAfter、addClass、格式化时间
  • 原文地址:https://www.cnblogs.com/f91og/p/9462101.html
Copyright © 2020-2023  润新知