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.
Subscribe to see which companies asked this question
思路分析:
对于任意长度的字符串,我们可以把字符串s1分为a1,b1两个部分,s2分为a2,b2两个部分,满足((a1~a2) && (b1~b2))或者 ((a1~b2) && (a2~b1))
代码如下:
class Solution {
public:
bool isScramble(string s1, string s2)
{
if (s1.size() != s2.size())
{
return false;
}
else
{
int len = s1.size();
bool*** dp = new bool**[len];
//bool dp[len][len][len];
for (int i = 0; i<len; i++)
{
dp[i] = new bool*[len];
for (int j = 0; j<len; j++)
{
dp[i][j] = new bool[len];
}
}
for (int i = 0; i<len; i++)
{
for (int j = 0; j<len; j++)
{
dp[0][i][j] = (s1[i] == s2[j]);
}
}
for (int l = 2; l <= len; l++)
{
for (int i = 0; i + l <= len; i++)
{
for (int j = 0; j + l <= len; j++)
{
dp[l - 1][i][j] = false;
for (int k = 1; k <= l - 1; k++)
{
if (dp[k - 1][i][j] && dp[l - k - 1][i + k][j + k])
{
dp[l - 1][i][j] = true;
}
else if (dp[k - 1][i][j + l - k] && dp[l - k - 1][i + k][j])
{
dp[l - 1][i][j] = true;
}
}
}
}
}
return dp[len - 1][0][0];
}
}
};
核心代码解析:
result[l][i][j]表示s1[i...i+l]是否可以由s2[j...j+l]变化得来。