题目描述
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.
解题思路
思路一:传统的递归方法(会超时)
- 划分字符串,将数组划分为[0,i]和[i,n-1]的子字符串(其中0<i<n);
- 判断[0,i]是否是回文数,如果是的话求cuts([i,n-1]),如果cuts([i,n-1])+ 1 < min,则min = cuts([i,n-1]) + 1;
- 循环1、2,直到i==n - 1;
思路二:动态规划(原文出处)
首先我们先定义几个变量:
cuts[i] = min{cuts[i], cuts[j+1] + 1}; 这样最后cuts[0] - 1便为 字符串str的最小的切割数!!!!
- len = str.length(); 字符串的长度;
- int[] cuts = new int[len + 1]; cuts数组,cuts[i] 表示 以 i 开头到len结尾的子串 要达到题意需要的最少切割数(最终 cuts[0]就是我们要的结果)【初始化 cuts[i] = len - i, 因为最坏情况以 i 开头到len结尾的子串要切割数就是每个字符都切一次】;
- int[][] matrix = new int[len][len]; //设置出一个邻接矩阵数组,它所表示的意思:如matrix[i][j] = true, 表示 子串 sub(i, j) 是满足回文字符串条件的!那么判断matrix[i][j] 是否满足回文字符串的条件是: matrix[i+1][j-1] == true (表示sub(i+1,j-1)是满足回文字符串) && str[i] == str[j] 或者 j - i < 2 && str[i] == str[j] (即如果j - i == 1时,为两个字符相等,如果j - i == 0时,为同一个字符)
cuts[i] = min{cuts[i], cuts[j+1] + 1}; 这样最后cuts[0] - 1便为 字符串str的最小的切割数!!!!
代码
递归方法:
public int minCut(String s) {
return getMinCut(s, s.length());
}
public int getMinCut(String s, int min) {
if (isPalindrome(s)) {
return 0;
}
for (int i = 1; i < s.length(); i++) {
String subStr1 = s.substring(0, i);
String subStr2 = s.substring(i, s.length());
if (isPalindrome(subStr1)) {
int cuts = minCut(subStr2);
if (cuts + 1 < min) {
min = cuts + 1;
}
}
}
return min;
}
public static boolean isPalindrome(String s) {
int start = 0;
int end = s.length() - 1;
while (start < end) {
if (s.charAt(start) == s.charAt(end)) {
start++;
end--;
} else {
return false;
}
}
return true;
}
动态规划:
public int minCut(String s) {
int min = 0;
int len = s.length();
boolean[][] matrix = new boolean[len][len];
int cuts[] = new int[len+1];
if (s == null || s.length() == 0)
return min;
for (int i=0; i<len; ++i){
cuts[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))
|| (s.charAt(i) == s.charAt(j) && matrix[i+1][j-1]))
{
matrix[i][j] = true;
cuts[i] = getMinValue(cuts[i], cuts[j+1]+1);
}
}
}
min = cuts[0];
return min-1;
}
public int getMinValue(int a, int b){
return a > b ? b : a;
}