本来想列举所有的情况出来然后再一一匹配,最后看题解发现有另外一种方法,虽然我这个只faster than3.19%
思路:仔细推倒可以发现,把字符串的每两个子串想象成二叉树的两个孩子时,这两个子串里的字符将不会再有机会相互移动,因为他们已经分成了左子树右子树,所以可以想到遍历字符串,截取字符串左右两部分,假设[0:i]和[i:]那么s2也应该在相同的位置上截取,如果他们包含的元素相同(不用顺序一致),则递归调用,注意,这里还有一种情况,我一开始没有考虑到,即s1为abb s2为bba时,所以想到还有一种情况是一开始就需要交换,我就抖了个机灵,reverse s1,别问我怎么想到的,蒙就完事儿了,不过注意Recursive里递归调用的是isScramble,其实程序可以写的更清楚一点,但是我太懒了,从我上面的抖机灵你们就能发现了
class Solution {
public:
bool Recursive(string s1, string s2) {
if (s1 == s2)return true;
int n = s1.length();
for (int i = 1; i < n; ++i) {
int len = i;
string t_s1_1 = s1.substr(0, len);
string t_s1_2 = s1.substr(len);
string t_s2_1 = s2.substr(0, len);
string t_s2_2 = s2.substr(len);
cout << t_s1_1 << " " << t_s1_2 <<"+"<<t_s2_1<<" "<<t_s2_2<< endl;
string s_s1_1 = t_s1_1; sort(s_s1_1.begin(), s_s1_1.end());
string s_s1_2 = t_s1_2; sort(s_s1_2.begin(), s_s1_2.end());
string s_s2_1 = t_s2_1; sort(s_s2_1.begin(), s_s2_1.end());
string s_s2_2 = t_s2_2; sort(s_s2_2.begin(), s_s2_2.end());
if (s_s1_1 == s_s2_2&&s_s1_2 == s_s2_1) { swap(t_s1_1, t_s1_2); swap(s_s1_1, s_s1_2); }//swap to right position
if (s_s1_1 == s_s2_1&&s_s1_2 == s_s2_2) {//if match
if (isScramble(t_s1_1, t_s2_1) && isScramble(t_s1_2, t_s2_2))return true;
}
}
return false;
}
bool isScramble(string s1, string s2) {
string R_s1 = s1;
reverse(R_s1.begin(), R_s1.end());
if (Recursive(s1, s2) || Recursive(R_s1, s2))return true;
else return false;
}
};