Topic links
Title Requirements:
Given A string S1, we may represent it as a binary tree by partitioning it to the Non-empty substrings Recursivel Y.
Below is one possible representation of S1 = "great"
:
Great / gr eat/\ / g r E at / a t
To scramble the string, we are choose any non-leaf node and swap it to the children.
For example, if we choose the node "gr"
and swaps its-children, it produces a scrambled string "rgeat"
.
Rgeat / RG eat/\ / r G e at / a t
We say is "rgeat"
a scrambled string of "great"
.
Similarly, if we continue to swap the children of nodes "eat"
"at"
and, it produces a scrambled string "rgtae"
.
Rgtae / RG tae/\ / r G ta e / t a
We say is "rgtae"
a scrambled string of "great"
.
Given strings S1 and S2 of the same length, determine if S2 is a scrambled string of S1.
This problem is referenced from one post and another blog post:
This is actually a three-dimensional dynamic programming topic, we propose maintenance amount Res[i][j][n], where I is the starting character of S1, J is the starting character of S2, and N is the current string length,Res[i][j][len] It is said that the string with the length len of the beginning of S1 and S2, respectively, of I and J, is not mutually scramble, and the answer should be res[0][0][s1.size()]
.
With maintenance, we'll look at recursion, which is how to get res[i][j][len by historical information]. Judging this is not satisfied, in fact we first is the current s1[i...i+len-1] string hack into two parts, and then divided into two cases: the first is left and S2[j...j+len-1] The left part is not scramble, as well as the right and s2[j...j+ Len-1] Right part is not scramble, the second case is left and s2[j...j+len-1] right part is not scramble, and right and s2[j...j+len-1] The left part is not scramble. If one of the above two cases is established, the explanation s1[i...i+len-1] and s2[j...j+len-1] is scramble. We have historical information as to whether these left and right parts are scramble, because all cases with a length of less than n are solved in front (that is, the length is the outermost loop).
Above said is the case of splitting a knife, for s1[i...i+len-1] we have len-1 seed splitting method, in these splitting method as long as there is a form, then two string is scramble.
Summing up recursion is res[i][j][len] = | | (Res[i][j][k]&&res[i+k][j+k][len-k] | | res[i][j+len-k][k]&&res[i+k][j][len-k]) for all 1<=k<len , that is, the result of all len-1 seed splitting method or operation. Because the information is computed, for each type of cleavage only a constant operation is required, so the solution recursion is required O (len) (because of the len-1 seed splitting method).
The procedure is as follows:
1 classSolution {2 Public:3 BOOLIsscramble (stringS1,stringS2) {4 intSzS1 =s1.size ();5 intSzS2 =s2.size ();6 if(SzS1! =szS2)7 return false;8 if(SzS1 = =0&& SzS2 = =0)9 return true;Ten Onevector<vector<vector<BOOL> > > DP (szS1, vector<vector<BOOL> > (szS2, vector<BOOL> (szS1 +1,false))); A for(inti =0; i < szS1; i++) - for(intj =0; J < SzS2; J + +) -dp[i][j][1] = s1[i] = =S2[j]; the - for(intLen =1; Len < szS1 +1; len++) - for(inti =0; I < Szs1-len +1; i++) - for(intj =0; J < Szs2-len +1; J + +) + for(intK =1; K < Len; k++) - if(Dp[i][j][k] && dp[i+k][j+k][len-k] | | dp[i][j+len-k][k] && DP[I+K][J][LEN-K])//back and forth, before and after + { ADp[i][j][len] =true; at Break; - } - - returndp[0][0][SZS1]; - } -};
Leetcode "Dynamic planning": Scramble String