开始的想法:暴力模拟
直接模拟,题目的意思是根节点下的两个孩子可以交换,就递归模拟。然而后面发现根节点的位置似乎并不是固定的,故失败。
我的代码:错误代码
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Solution {
public:
bool isScramble(string s1, string s2) {
if(s1 == s2)
return true;
return judgeScramble(0,s1.length()-1,s1,s2);
}
bool judgeScramble(int from,int to,string str,string pattern)
{
cout<<from<<" "<<to<<" "<<str.size()<<endl;
int mid = (from+to-1)/2;//aim root
//exchange its two children
string newstr = str.substr(0,from)+str.substr(mid+1,to-mid)+str.substr(from,mid+1-from)+str.substr(to+1);
cout<<newstr<<endl;
if(newstr == pattern)
return true;
bool s1 = false,s2 = false,s3 = false,s4 = false;
if(mid-from>=1)
{
s1 = judgeScramble(from,from+to-mid-1,newstr,pattern);
s2 = judgeScramble(from,mid,str,pattern);
}
if(s1||s2)
return true;
if(to-mid>1)
{
s3 = judgeScramble(from+to-mid,to,newstr,pattern);
s4 = judgeScramble(mid+1,to,str,pattern);
}
return s3||s4;
}
};
int main(void)
{
Solution s;
cout<<s.isScramble("abb","bab")<<endl;
return 0;
}
动态规划
既然根节点可以交换,那就去反复枚举根节点(根节点可以从第一个点到最后一个,只要保证孩子的长度大于等于1即可),然后判断如果发生交换时两个子串是否符合条件,如果没有发生交换时两个子串是否满足条件。只要有一个满足条件即可。
class Solution {
public:
bool isScramble(string s1, string s2) {
if(s1==s2)
return true;
int len = s1.length();
int count[26] = {0};
for(int i=0; i<len; i++)
{
count[s1[i]-'a']++;
count[s2[i]-'a']--;
}
for(int i=0; i<26; i++)
{
if(count[i]!=0)
return false;
}
for(int i=1; i<=len-1; i++)
{
if( isScramble(s1.substr(0,i), s2.substr(0,i)) && isScramble(s1.substr(i), s2.substr(i)))
return true;
if( isScramble(s1.substr(0,i), s2.substr(len-i)) && isScramble(s1.substr(i), s2.substr(0,len-i)))
return true;
}
return false;
}
};