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.
Solution: 1. 3-dimensional dp. Contributed by yinlinglin. I really appreciate it!
'dp[k][i][j] == true' means string s1(start from i, length k) is a scrambled string of
string s2(start from j, length k).
2. Recursion + pruning.
1 class Solution { 2 public: 3 bool isScramble(string s1, string s2) { 4 if(s1.size() != s2.size()) return false; 5 int N = s1.size(); 6 bool dp[N+1][N][N]; 7 for (int k = 1; k <= N; ++k) 8 for (int i = 0; i <= N-k; ++i) 9 for (int j = 0; j <= N-k; ++j) 10 { 11 dp[k][i][j] = false; 12 if (k == 1) 13 dp[1][i][j] = (s1[i] == s2[j]); 14 for (int p = 1; p < k && !dp[k][i][j]; ++p) 15 if (dp[p][i][j] && dp[k-p][i+p][j+p] || dp[p][i][j+k-p] && dp[k-p][i+p][j]) 16 dp[k][i][j] = true; 17 } 18 return dp[N][0][0]; 19 } 20 };