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.
这道题,最开始的思路如下。使用一个int数组mark,mark[i]代表到达当前位置,需要切的刀数。提交以后发现超时。
public int minCut(String s) {
if(s==null)
return 0;
int length=s.length();
if(length<=1)
return 0;
int mark[]=new int[length+1];
mark[0]=0;
for(int i=0;i<length;i++){
for(int j=i;j<length;j++){
if(isPalindrome(s, i, j)){
if(mark[j+1]==0)
mark[j+1]=mark[i]+1;
else
mark[j+1]=Math.min(mark[j+1], mark[i]+1);
}
}
}
return mark[length]-1;
}
private boolean isPalindrome(String s,int index1,int index2){
while(index1<index2){
if(s.charAt(index1)!=s.charAt(index2))
return false;
index1++;
index2--;
}
return true;
}
然后想到了动态规划的思路。但是如何规划,还是让我想了好久,没有找到合适的方法,于是参考了一下http://blog.csdn.net/doc_sgl/article/details/13418125的内容。得到如下的解法:
其中D[i]代表从第i个位置到最后需要切的刀数。
p[i][j]字符串s[i~j]是否回文
满足p[i][j]回文的基本条件是s.charAt(i)==s.charAt(j),其次,还要求符合以下两点之一:
(1)j-i<2
(2)p[i+1][j-1]回文
public int minCut(String s){
int len=s.length();
int[] D=new int[len+1];
boolean[][] p=new boolean[len][len];
for(int i=0;i<=len;i++)
D[i]=len-i;
for(int i=len-1;i>=0;i--){
for(int j=i;j<len;j++){
if(s.charAt(i)==s.charAt(j)&&(j-i<2 || p[i+1][j-1])){
p[i][j]=true;
D[i]=Math.min(D[i], D[j+1]+1);
}
}
}
for(int i=0;i<p.length;i++)
System.out.println(Arrays.toString(p[i]));
System.out.println(Arrays.toString(D));
return D[0]-1;
}