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.
动态规划 这一类的题目最重要的就是保护现场。。 不能改变现场的情况:
比如这里 就不能
if(cur < max){ findmin(s,i + 1,cur + 1); }
写成:
if(cur < max){
cur ++;
pointer = i + 1;
findmin(s,pointer,cur);
}
会影响后面的同级别的其他操作。
1 public class Solution { 2 int max = 0; 3 public int minCut(String s) { 4 // Start typing your Java solution below 5 // DO NOT write main() function 6 max = s.length() - 1; 7 int pointer = 0; 8 if(s.length() == 0){ 9 return 0; 10 } 11 int cur = 0; 12 findmin(s,pointer,cur); 13 int k = max; 14 return max; 15 } 16 public void findmin(String s,int pointer,int cur){ 17 int len = s.length(); 18 if(pointer == len){ 19 if(cur - 1 < max){ 20 max = cur - 1; 21 } 22 } 23 for(int i = pointer; i < len; i ++){ 24 int flag = 0; 25 if(i == pointer){ 26 findmin(s,i + 1,cur + 1); 27 } 28 else if((i - pointer + 1) % 2 == 0){ 29 int mid = (i - pointer - 1)/2; 30 int j = 0; 31 for(; j < mid + 1; j ++){ 32 if(s.charAt(j+pointer) != s.charAt(i - j)){ 33 flag = 1; 34 break; 35 } 36 } 37 if(flag == 0){ 38 if(cur < max){ 39 findmin(s,i + 1,cur + 1); 40 } 41 } 42 } 43 else{ 44 int mid = (i - pointer) / 2 - 1; 45 int j = 0; 46 for(; j < mid + 1; j ++){ 47 if(s.charAt(j+pointer) != s.charAt(i - j)){ 48 flag = 1; 49 break; 50 } 51 } 52 if(flag == 0){ 53 if(cur < max){ 54 findmin(s,i + 1,cur + 1); 55 } 56 } 57 } 58 } 59 } 60 }
第四遍:
分为两步,第一步找到所有是palindrome的substring。 O(n^2).
第二步是算从0- i,的最小的cut数。1—D dp
dp[i] = 0, if status[0][i] = true(从0到i刚好是个palindrome)
dp[i] = min(dp[k - 1] + 1), if(k 到 i 刚好是palindrome, k 在[1, i]中)
1 public class Solution { 2 /* 3 this is an 1-D DP problem 4 with an 2-D information 5 dp[j] = min(dp[k](i <= k <= j - 1) + 1(if [k, j] is palindrome), 0 (if[i, j] is palindrome)); 6 dp[i] = 0; 7 i - start point; j - end point. 8 */ 9 public int minCut(String s) { 10 if(s == null || s.length() == 0) return 0; 11 int len = s.length(); 12 int[] dp = new int[len]; 13 boolean[][] status = new boolean[len][len]; 14 for(int i = 0; i < s.length() * 2; i ++){ 15 int left = i / 2; 16 int right = (i + 1) / 2; 17 for(; left > -1 && right < s.length(); left --, right ++){ 18 if(s.charAt(left) == s.charAt(right)){ 19 status[left][right] = true; 20 }else{ 21 break; 22 } 23 } 24 } 25 for(int i = 0; i < len; i ++){ 26 if(status[0][i] == true) dp[i] = 0; 27 else{ 28 dp[i] = Integer.MAX_VALUE; 29 for(int j = 1; j <= i; j ++){ 30 if(status[j][i] == true){ 31 dp[i] = Math.min(dp[i], dp[j - 1] + 1); 32 } 33 } 34 } 35 } 36 return dp[len - 1]; 37 } 38 }