Palindrome Partitioning II
这个题意思挺好理解,提供一个字符串s,将s分割成多个子串,这些字串都是回文,要求输出分割的最小次数。
Example:
Input: "aab"
Output: 1
Explanation: The palindrome partitioning ["aa","b"] could be produced using 1 cut.
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]的值便于后面的过程中回文条件的判断。
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 }
来源:https://www.cnblogs.com/messi2017/p/9904220.html