Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrings recursively.
Below is one possible representation of s1 = “great”:
great
/
gr eat
/ \ /
g r e at
/
a t
To scramble the string, we may choose any non-leaf node and swap its two children.
For example, if we choose the node “gr” and swap its two children, it produces a scrambled string “rgeat”.
rgeat
/
rg eat
/ \ /
r g e at
/
a t
We say that “rgeat” is a scrambled string of “great”.
Similarly, if we continue to swap the children of nodes “eat” and “at”, it produces a scrambled string “rgtae”.
rgtae
/
rg tae
/ \ /
r g ta e
/
t a
We say that “rgtae” is a scrambled string of “great”.
Given two strings s1 and s2 of the same length, determine if s2 is a scrambled string of s1.
Example 1:
Input: s1 = “great”, s2 = “rgeat”
Output: true
Example 2:
Input: s1 = “abcde”, s2 = “caebd”
Output: false
func isScramble(s1 string, s2 string) bool {
if len(s1) != len(s2) {
return false
}
if s1==s2 {
return true
}
lg := len(s1)
dp := make([][][]bool, lg)
for i := 0; i < lg; i++ {
dp[i] = make([][]bool,lg)
for j := 0; j < lg; j++ {
dp[i][j] = make([]bool,lg+1)
dp[i][j][1] = s1[i]==s2[j]
}
}
for l := 2; l <= lg; l++ {
for i := 0; i <= lg-l; i++ {
for j := 0; j <= lg-l; j++ {
for k := 1; k < l; k++ {
if (dp[i][j][k] && dp[i+k][j+k][l-k]) || (dp[i][j+l-k][k] && dp[i+k][j][l-k]) {
dp[i][j][l] = true
break
}
}
}
}
}
return dp[0][0][lg]
}