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.
给出两个字符串,判断第二个字符串是否能从第一个字符串“搅乱“得来。“搅乱“的规则是对每个字符串递归的进行旋转(不旋转也行)两个子字符串。用递归的方法即可。通过递归划分子问题:对当前两个字符串s1,s2,如果s1(0,i)和s2(0,i)符合“搅乱”规则且s1(i,n1)和s2(i,n2)符合“搅乱”规则(交换),或者s1(0,i)和s2(n2-i,n2)符合“搅乱”规则且s1(i,n1)和s2(0,i)符合“搅乱”规则,则说明当前两个字符串符合“搅乱”规则。在递归过程中为了减少递归次数,通过检测两个字符串字符数和所含字符是否全都一样来剪枝。
代码:
class Solution
{
public:
bool isScramble(string s1, string s2)
{
if(s1 == s2) return true;
int n1 = s1.size(), n2 = s2.size();
if(n1 != n2) return false;
int cnt[256] = {0};
for(int i = 0; i < n1; ++i)
{
++cnt[s1[i]];
--cnt[s2[i]];
}
for(int i = 0; i < 256; ++i)
{
if(cnt[i] != 0)
{
return false;
}
}
for(int i = 1; i < n1; ++i)
{
if((isScramble(s1.substr(0, i), s2.substr(0, i)) && isScramble(s1.substr(i), s2.substr(i)))
|| (isScramble(s1.substr(0, i), s2.substr(n2 - i)) && isScramble(s1.substr(i), s2.substr(0, n2 - i))) )
{
return true;
}
}
return false;
}
};