LeetCode 132.分割回文串II

LeetCode 132.分割回文串II

执行用时 :13 ms, 在所有 Java 提交中击败了71.11%的用户

判断回文串:

回文串分两种:长度为奇数、长度为偶数
考虑生成回文串长度为奇数的回文串会有一个数作为中心,沿两侧扩展。,长度为偶数的回文串会有一条线作为对称轴,向两侧扩展。
那么找到所有的回文串,将每个字符按奇数长度和偶数长度各生成一轮回文串,新建一个二维数组 sign[i][j]**,表示从ij是否是回文串
LeetCode 132.分割回文串II_第1张图片

确定状态:

LeetCode 132.分割回文串II_第2张图片
关注最优策略中最后一段回文串,设为S[j..N-1],设f[j]为在j之前最少可以划分多少个回文串

子问题:

由求S[0..N-1]的最优策略分解为求S[0..j-1]的最优策略。

转移方程:

f [ i ] = m i n j = 0 , … , i − 1 { f [ j ] + 1 ( S [ j . . i − 1 ] 是 回 文 串 ) } f[i] = min_{j=0,…,i-1}\{f[j] + 1(S[j..i-1]是回文串)\} f[i]=minj=0,,i1{f[j]+1(S[j..i1])}
----> f [ i ] = m i n j = 0 , … , i − 1 { f [ j ] + 1 ( s i g n [ j ] [ i − 1 ] = T r u e ) } f[i] = min_{j=0,…,i-1}\{f[j] + 1(sign[j][i-1] = True)\} f[i]=minj=0,,i1{f[j]+1(sign[j][i1]=True)}

初始条件和边界:

f[0]=0,最后答案为f[n]-1,因为原题求的是分割次数,f[]代表的是回文串个数。

class Solution {
    private boolean[][] judge(char []ch)
    {
        int m=ch.length;
        boolean [][]f=new boolean[m][m];
        for(int i=0;i<m;i++)
            Arrays.fill(f[i],false);
        for(int c=0;c<m;c++)\\奇数长度回文串
        {
            for(int j=c,i=c;i>=0&&j<m&&ch[i]==ch[j];)
            {
                f[i][j]=true;
                i--;j++;
            }
        }
         for(int c=0;c<m;c++)\\偶数长度回文串
        {
            for(int j=c+1,i=c;i>=0&&j<m&&ch[i]==ch[j];)
            {
                f[i][j]=true;
                i--;j++;
            }
        }
        return f;
    }
    public int minCut(String s) {
        char []ch=s.toCharArray();
        int m=ch.length;
        if(m==0)
            return 0;
        boolean [][]sign=judge(ch);
        int []f=new int[m+1];
        f[0]=0;
        for(int i=1;i<=m;i++)\\dp
        {
            f[i]=Integer.MAX_VALUE;
            for(int j=0;j<i;j++)
            {
                if(sign[j][i-1])
                    f[i]=Math.min(f[i],f[j]+1);
            }
        }
        return f[m]-1;
    }
}

你可能感兴趣的:(Leetcode)