Given A string s, partition s such that every substring of the partition are 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.
The following:
This problem needs to be done with dynamic planning, if using the Dfs method of I will be tle.
First set the DP variable cuts[len+1]. Cuts[i] Represents the number of cuts from position I to the Len position (inclusive, that is, [I, Len]) (The Len position is empty).
Initially, it is len-i. For example Aab,cuts[0]=3, is the worst case of every character must be cut: a|a|b| ' ‘。 CUTS[1] = 2, starting from the I=1 position, a|b| ' ‘。
CUTS[2] = 1 b| ' ‘。 Cuts[3]=0, which is the position of the Len, is a null character and does not require cutting.
The above cuts array is used to help calculate the minimum cuts.
A DP two-dimensional array matrixs[i][j] is also required to denote whether the string [I,j] is a palindrome from the first position (inclusive) to the J-position (inclusive).
How to tell if a string [I,j] is a palindrome?
1. Matrixs[i+1][j-1] is a palindrome and S.charat (i) = = S.charat (j).
2. I==j (I,j is a character)
3. J=i+1 (i,j adjacent) and S.charat (i) = = S.charat (j)
When the string [I,j] is a palindrome, it is explained that the minimum cut number from position I to the position of the string Len can be updated,
So is the minimum cut number from the j+1 position to the Len position plus the [i,j]| [J+1,len-1] In the middle of this cut.
That is, Math.min (Cuts[i], cuts[j+1]+1)
Finally, return to Cuts[0]-1. The final result is to remove the extra one cut for the position of the first Len.
C + + Implementation code:
#include <iostream>#include<string>#include<cstring>using namespacestd;classSolution { Public: intMincut (strings) {if(S.empty ())return 0; intn=s.length (); BOOLMatrix[n][n]; intcut[n+1]; memset (Matrix,false,sizeof(matrix)); memset (Cut,0,sizeof(cut)); inti,j; for(i=0; i<n;i++) Cut[i]=n-i; for(i=n-1; i>=0; i--) { for(j=i;j<n;j++) { if((s[i]==s[j]&&j-i<2)|| (s[i]==s[j]&&matrix[i+1][j-1])) {Matrix[i][j]=true; Cut[i]=min (cut[i],cut[j+1]+1); } } } returncut[0]-1; }};intMain () {solution S; intResult=s.mincut (string("Ababababababababababababcbabababababababababababa")); cout<<result<<Endl;}
Using the backtracking method will time out for large collections:
#include <iostream>#include<vector>#include<string>#include<climits>using namespacestd;classsolution{ Public: intMincut (strings) {if(S.empty ())return 0; Vector<string>path; intmin=Int_max; Helper (S,0, path,min); returnmin; } voidHelperstringSintstart,vector<string> &path,int&min) { intn=path.size (); inti; intsum=0; for(intj=0; j<n; J + +) {sum+=path[j].size (); } if(sum== (int) S.size ()) {if((int) Path.size ()-1<min) min=path.size ()-1; return; } for(i=1; I<= (int) s.size () &&start+i<= (int) S.size (); i++) { stringtmp=s.substr (start,i); if(!ispalindrome (TMP))Continue; Path.push_back (TMP); Helper (S,start+i,path,min); Path.pop_back (); } } BOOLIspalindrome (strings) {if(S.empty ())return true; intI=0; intJ=s.length ()-1; while(i<=j) {if(s[i]!=S[j])return false; I++; J--; } if(i>j)return true; return false; }};intMain () {solution S; intResult=s.mincut (string("Abababababab")); cout<<result<<Endl;}
Palindrome Partitioning II