# LeetCode | Scramble String（字符交换）

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.

``````class Solution {
public:
bool isScramble(string s1, string s2) {
if(s1.size() != s2.size())
return false;
return JudgeScramble(s1,0,s1.size()-1,s2,0,s2.size());

}
bool JudgeScramble(string s1,int begin1,int end1,string s2,int begin2,int end2){
if(begin1 > end1)
return true;
int i = begin2;
while(i <= end2){
if(s1[begin1] == s2[i])
break;
i++;
}
if(i > end2)
return false;
int len = i-begin2;
return JudgeScramble(s1,begin1+1,begin1+len,s2,begin2,i-1) && JudgeScramble(s1,begin1+len+1,end1,s2,i+1,end2);
}
};``````

``````bool isScramble(string s1, string s2) {
int lens1,lens2;
lens1 = s1.length();
lens2 = s2.length();
if(lens1!=lens2)
return false;
if(lens1==0)
return true;
if (lens1==1)
{
return s1[0]==s2[0];
}
if (lens2==2)
{
return (s1[0]==s2[0]&&s1[1]==s2[1])||(s1[0]==s2[1]&&s1[1]==s2[0]);
}
string stra1,stra2,strb1,strb2;
for(int i=1;i<lens1;i++)
{
stra1 = s1.substr(0,i);
stra2 = s1.substr(i,lens1-i);
strb1 = s2.substr(0,i);
strb2 = s2.substr(i,lens2-i);
if (isScramble(stra1,strb1)&&isScramble(stra2,strb2))
{
return true;
}
stra1 = s1.substr(0,lens1-i);
stra2 = s1.substr(lens1-i,i);
if (isScramble(stra1,strb2)&&isScramble(stra2,strb1))
{
return true;
}
}
return false;
}  ``````

dp[i][j][k] 代表了s1从i开始，s2从j开始，长度为k的两个substring是否为scramble
string。

1. 如果两个substring相等的话，则为true

2. 如果两个substring中间某一个点，左边的substrings为scramble string，同时右边的substrings也为scramble string，则为true

3. 如果两个substring中间某一个点，s1左边的substring和s2右边的substring为scramble
string, 同时s1右边substring和s2左边的substring也为scramble string，则为true

``````class Solution {
public:
bool isScramble(string s1, string s2) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
if (s1.length() != s2.length()) {
return false;
}
int length = s1.length();
bool f[length][length][length];
memset(f, false, sizeof(bool) * length * length * length);

for (int k = 1; k <= length; k++) {
for (int i = 0; i <= length - k; i++) {
for (int j = 0; j <= length - k; j++) {
if (k == 1) {
f[i][j][k] = s1[i] == s2[j];
}
else {
for (int l = 1; l < k; l++) {
if ((f[i][j][l] && f[i + l][j + l][k - l]) || (f[i][j + k - l][l] && f[i + l][j][k - l])) {
f[i][j][k] = true;
break;
}
}
}
}
}
}

return f[0][0][length];
}
};``````