LeetCode_132分割回文串II

给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。

返回符合要求的最少分割次数。

示例:

输入: “aab”
输出: 1
解释: 进行一次分割就可将 s 分割成 [“aa”,“b”] 这样两个回文子串。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-partitioning-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
    public int minCut(String s) {
        int length = s.length();
		//dp[i][j]表示[i,j]是否是回文串
		boolean[][] dp = new boolean[length][length];
		//考虑所有长度的子串
		for (int len = 1; len <= length; len++) {
		    //从每个下标开始
		    for (int i = 0; i <= s.length() - len; i++) {
		        int j = i + len - 1;
		        dp[i][j] = s.charAt(i) == s.charAt(j) && (len < 3 || dp[i + 1][j - 1]);
		    }
		}
		//numdp[i][j]记录[i,j]的最小分割次数
		int[][] numdp = new int[length][length];
		for(int i=0;i<length;i++) {
			for(int j=i;j<length;j++) {
				numdp[i][j] = j-i+1;//最大为i到j的长度
			}
		}
		for(int len=1;len<=length;len++) {
			for(int i=0;i<=s.length()-len;i++) {
				int j = i+len-1;
				if(j==i) {
					numdp[i][j] = 1;
				}else if(j==i+1) {
					if(dp[i][j]) {
						numdp[i][j] = 1;
					}else {
						numdp[i][j] = 2;
					}
				}else {
					if(dp[i][j]) {
						numdp[i][j] = 1;
					}else {
						for(int k=i;k<j;k++) {
							if(dp[k+1][j]) {
								numdp[i][j] = Math.min(numdp[i][j], numdp[i][k]+1);
							}else {
								numdp[i][j] = Math.min(numdp[i][j], numdp[i][k]+numdp[k+1][j]);
							}
						}
					}
				}
			}
		}
		return numdp[0][length-1]-1;
    }

}

你可能感兴趣的:(LeetCode题解)