(LeetCode 每日一题) 132. 分割回文串 II (动态规划dp)

题目:132. 分割回文串 II

(LeetCode 每日一题) 132. 分割回文串 II (动态规划dp)_第1张图片
思路:最大分割次数为n-1,也就是分割为单个字符的次数。
通过动态规划dp,可以得出字符串之间的哪段是回文串。
再通过动态规划dp,算出使区间[0,i]为回文分割串所需要的最小分割次数f[i]。最后答案为f[n-1],时间复杂度为0(n^2)。

class Solution {
public:
    int n;
    vector<vector<bool>> v;
    //动态规划一:判断回文串
    void dp1(string s){
        v.assign(n,vector<bool>(n,0));
        for(int lens=1;lens<=n;lens++){
            for(int i=0;i+lens-1<n;i++){
                int j=i+lens-1;
                if(lens==1) v[i][j]=1;
                else if(lens==2) v[i][j]=s[i]==s[j];
                else v[i][j]=v[i+1][j-1]&&s[i]==s[j];
            }
        }
    }
    //动态规划二:判断回文串
    void dp2(string s){
        v.assign(n,vector<bool>(n,1));
        for(int i=n-1;i>=0;i--){
            for(int j=i+1;j<n;j++){
                v[i][j]=v[i+1][j-1]&&s[i]==s[j];
            }
        }
    }
    int minCut(string s) {
        n=s.size();
        dp1(s);
        //dp2(s);
        vector<int> f(n,0);
        //动态规划得出最小分割次数
        for(int i=1;i<n;i++){
        	//区间【0,i】为回文串
            if(v[0][i]) continue;
            //区间[0,i]的最大分割次数
            f[i]=i;
            //优化
            for(int j=i;j>0;j--){
                if(v[j][i]) f[i]=min(f[i],f[j-1]+1);
            }
        }
        return f[n-1];
    }
};

JAVA版本:

class Solution {
    int n;
    boolean[][] v;
    void dp1(char[] s){
        v = new boolean[n][n];
        for(int lens=1;lens<=n;lens++){
            for(int i=0;i+lens-1<n;i++){
                int j=i+lens-1;
                if(lens==1) v[i][j]=true;
                else if(lens==2) v[i][j]=(s[i]==s[j]);
                else v[i][j]=v[i+1][j-1]&&s[i]==s[j];
            }
        }
    }
    void dp2(char[] s){
        v = new boolean[n][n];
        for(boolean[] x:v){
            Arrays.fill(x,true);
        }
        for(int i=n-1;i>=0;i--){
            for(int j=i+1;j<n;j++){
                v[i][j]=v[i+1][j-1]&&s[i]==s[j];
            }
        }
    }
    public int minCut(String s) {
        n=s.length();
        char[] c=s.toCharArray();
        //dp1(c);
        dp2(c);
        int[] f= new int[n];
        for(int i=1;i<n;i++){
            if(v[0][i]==true) continue;
            f[i]=i;
            for(int j=i;j>0;j--){
                if(v[j][i]==true) f[i]=Math.min(f[i],f[j-1]+1);
            }
        }
        return f[n-1];
    }
}

你可能感兴趣的:(java版刷题,LeetCode,leetcode,动态规划,算法,java,c++)