https://www.youtube.com/watch?v=vunyW9zVrx4
Given a string s, partition s such that every substring of the partition is a palindrome.
Return the minimum cuts needed for a palindrome partitioning of s.
For example, given s = "aab"
,
Return 1
since the palindrome partitioning ["aa","b"]
could be produced using 1 cut.
题意分析:对输入的字符串进行划分,要求划分后的所有的子字符串都是回文串,求最小划分的个数。
1.定义两个数组cus[]以及ispalindrome[][]
(1)数组cuts[i]表示将位置0到i的子串划分为回文字串最小划分个数,例如 s="aab"
cuts[0] 表示划分"a"的最小划分个数,为0, 不需划分
cuts[1] 表示划分"aa"的最小划分个数,为0, 不需划分
cuts[2]表示划分"aab"的最小划分个数, 为1 ,划分为{aa,b}
(2)另外定义数组ispalindrome[j][i]表示字符串从位置j到位置i所表示的子字串是否为回文字串,根据回文字串的对称性质有下面等式成立:
if(charAt(i)==charAt(j) &&ispalindrome[j+1][i-1] == true) ispalindrome[j][i] = true
2.考虑一下边界情况:
(1)当i == j时, ispalindrome[j][i] = true
(2) 当charAt(i)==charAt(j) 且 i - j < 2时, 即i与j之间最多间隔一个字符且两边的字符相同时,此子字串为回文,ispalindrome[j][i] = true
3.计算过程
根据cuts[]定义,如果s的长度是len,则我们最终需要返回的结果是cuts[len-1]。 如何计算cuts[]?
(1)设cuts[i]的初始值为i, 即字符串按每个字符划分的个数, 一个字符不需划分,两个字符需要一次划分,以此类推。
(2)若从位置0到i的整个字串是回文,则不需要划分,即cuts[i] = 0
(3) 若从位置j(j<=i)到位置i为回文,则cuts[i] =Math.min(cuts[i], cuts[j-1] +1),即从j至i的回文做一次划分,j-1之前的字串最小划
分为cuts[j-1]
代码如下:
class Solution {
public int minCut(String s) {
if(s == null|| s.length() == 0) return 0;
int len = s.length();
int[] cuts = new int[len];
boolean[][] ispalindrome = new boolean[len][len];
cuts[0] = 0;
ispalindrome[0][0] = true;
for(int i = 1; i < len; i++){
int min = i;
for(int j = 0; j <=i; j++){
if(s.charAt(i) == s.charAt(j) &&( i-j < 2 || (j < len -1 && ispalindrome[j+1][i-1]))){
ispalindrome[j][i] = true;
min = j ==0 ? 0:Math.min(min, cuts[j-1] +1);
}
}
cuts[i] = min;
}
return cut[len -1];
}
}