@@ -45,12 +45,12 @@ int minCut(string s) {
4545 * -------------------
4646 *
4747 * Define res[i] = the minimum cut from 0 to i in the string.
48- * The result w =e need eventually is res[s.size()-1].
48+ * The result eventually is res[s.size()-1].
4949 * We know res[0]=0. Next we are looking for the optimal solution function f.
5050 *
5151 * For example, let s = "leet".
5252 *
53- * f(0) = 0; // minimum cut of str[0:0]="l", which is a palindrome, so not cut is needed.
53+ * f(0) = 0; // minimum cut of str[0:0]="l", which is a palindrome, so not cut is needed.
5454 * f(1) = 1; // str[0:1]="le" How to get 1?
5555 * f(1) might be: (1) f(0)+1=1, the minimum cut before plus the current char.
5656 * (2) 0, if str[0:1] is a palindrome (here "le" is not )
@@ -76,16 +76,24 @@ int minCut(string s) {
7676 * Also using the similar DP idea, we can construct the look-up table before the main part above,
7777 * so that the palindrome testing becomes the looking up operation. The way we construct the table is also the idea of DP.
7878 *
79- * e.g. mp[i][j]== true if str[i:j] is palindrome.
80- * mp[i][i]=true;
79+ * e.g. mp[i][j]=true if str[i:j] is palindrome.
80+ * mp[i][i]=true;
8181 * mp[i][j] = true if str[i]==str[j] and (mp[i+1][j-1]==true or j-i<2 ) j-i<2 ensures the array boundary.
8282 */
8383
8484
8585int minCut_DP (string& s) {
86+ // res[] is for minimal cut DP
8687 vector<int >res (s.size (),0 );
88+ // mp[][] is for palindrome checking DP
8789 bool mp[s.size ()][s.size ()];
8890
91+ // construct the pailndrome checking matrix
92+ // 1) matrix[i][j] = true; if (i==j) -- only one char
93+ // 2) matrix[i][j] = true; if (i==j+1) && s[i]==s[j] -- only two chars
94+ // 3) matrix[i][j] = matrix[i+1][j-1]; if s[i]==s[j] -- more than two chars
95+ //
96+ // note: 1) and 2) can be combined together
8997 for (int i=s.size ()-1 ;i>=0 ;i--){
9098 for (int j=i;j<s.size ();j++){
9199 if ((s[i]==s[j]) && (j-i<2 || mp[i+1 ][j-1 ])){
@@ -95,12 +103,18 @@ int minCut_DP(string& s) {
95103 }
96104 }
97105 }
106+ // minimal cut dp
98107 for (int i=0 ;i<s.size ();i++){
99- if (mp[0 ][i]){
108+ // if s[0..i] is palindrome, then no need to cut
109+ if (mp[0 ][i] == true ){
100110 res[i]=0 ;
101111 }else {
112+ // if s[0..i] isn't palindrome
113+ // then, for each 0 to i, find a "j" which meets two conditions:
114+ // a) s[j+1..i] are palindrome.
115+ // b) res[j]+1 is minimal
102116 int ms = s.size ();
103- for (int j=0 ;j<i;j++){
117+ for (int j=0 ; j<i; j++){
104118 if (mp[j+1 ][i] && ms>res[j]+1 ) {
105119 ms=res[j]+1 ;
106120 }
@@ -118,7 +132,7 @@ int minCutHelper(string &s, int steps, int& minSteps ) {
118132 if (minSteps <= steps) {
119133 return -2 ;
120134 }
121- // adding the cache
135+ // adding the cache to remove the duplicated calculation
122136 static map<string, int > cache;
123137 if ( cache.find (s)!=cache.end () ){
124138 if (s.size ()>0 )
@@ -174,14 +188,12 @@ void minCutHelper(string &s, int start, int steps, int& min ) {
174188 for (int i=s.size ()-1 ; i>=start; i--){
175189 // cut unnecessary DFS
176190 if ( min > steps && isPalindrome (s, start, i)) {
177- // if ( cache.find(i+1)==cache.end() ){
178191 minCutHelper (s, i+1 , steps+1 , min );
179- // cache[i+1] = true;
180- // }
181192 }
182193 }
183194}
184195
196+ // traditional palindrome checking function.
185197bool isPalindrome (string &s, int start, int end) {
186198
187199 while (start < end) {
0 commit comments