zoukankan      html  css  js  c++  java
  • 动态规划——Palindrome Partitioning II

    Palindrome Partitioning II
    这个题意思挺好理解,提供一个字符串s,将s分割成多个子串,这些字串都是回文,要求输出分割的最小次数。
    Example:
    Input: "aab"
    Output: 1
    Explanation: The palindrome partitioning ["aa","b"] could be produced using 1 cut.
    状态:这个题的状态也非常好理解,dp[i]表示将s[0..i]分割成回文子串的最小分割次数。然后不急于寻找状态转移方程,我们先要明确如何用代码判断一个字符串的某个部分是不是回文,其实也很好理解啊,咱们可以分块来理解,毕竟这是个算法题,不可能用常规的那种遍历一半的方式来判断。首先对于这个字符串的某个子串s[j..i](j<=i),满足它是回文的条件两条(1)s[j]==s[i]  (2)  只确定两端的两个字符还不够,当这个子串的长度小于4或者去掉两端的相同字符后还是回文即可。现在我们除了递推数组dp,再定义一个记录数组pa[j][i],如果s[j..i]是回文,则pa[j][i] = 1,否则为0。有了这两个条件,我们就可以总结状态转移方程了:
    dp[i] = min(dp[j-1]+1),当0<j<=i时,并且s[j..i]是回文时
    dp[i] = 0 ,当j=0,并且s[j..i]是回文时
    在具体的dp数组递推运算过程中,需要这两个分支,同时会更新pa[j][i]的值便于后面的过程中回文条件的判断。
     
     1 public int minCut(String s) {
     2         int slen = s.length();
     3         int[][]pa = new int[slen][slen];
     4         int[]dp = new int[slen];
     5         for(int i = 0;i<slen;i++)
     6             dp[i] = i;
     7         for(int i = 0;i<slen;i++)
     8             Arrays.fill(pa[i],0);
     9         for(int i = 1;i<slen;i++) {
    10             for(int j = 0;j<=i;j++) {
    11                 if(s.charAt(j)==s.charAt(i)&&((i-j<2)||pa[j+1][i-1]==1)) {
    12                     pa[j][i] = 1;
    13                     if(j!=0)dp[i] = Math.min(dp[i],dp[j-1]+1);
    14                     else dp[i] = 0;
    15                 }
    16             }
    17         }
    18         return dp[slen-1];
    19     }
  • 相关阅读:
    Storm
    Linux 网络配置
    .NET Remoting
    jwt
    new操作符
    元数据
    C# lock
    三十而立
    面试
    灯火
  • 原文地址:https://www.cnblogs.com/messi2017/p/9904220.html
Copyright © 2011-2022 走看看