第一种思路就是生成所以的翻转,然后比较是否和s2匹配,这个时间复杂度过高。
第二种思路就是在生成的时候,边比较。这里采用分治的方法(超时)
class Solution {
public:
bool isScramble(string s1, string s2) {
if(s1 == s2){
return true;
}
string b1 = s1, b2 = s2;
sort(b1.begin(), b1.end());
sort(b2.begin(), b2.end());
if(b1 != b2){
return false;
}
int n = s1.size();
for(int i = 1; i <= n - 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, n - i),s2.substr(i)) &&
isScramble(s1.substr(n - i), s2.substr(0, i))){
return true;
}
}
return false;
}
};
我们将这个过程改成区间DP
const int N = 32;
class Solution {
public:
bool dp[N][N][N];
bool isScramble(string s1, string s2) {
int n1 = s1.size(), n2 = s2.size();
if(n1 != n2){
return false;
}
int n = n1;
// dp[i][j][k]] 表示从s1第i位开始,长度为k的位,是否匹配从s2第j位开始,长度为k的位
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
dp[i][j][1] = (s1[i] == s2[j]);
}
}
for(int k = 2; k <= n; k++){
for(int i = 0; i + k <= n; i++){
for(int j = 0; j + k <= n; j++){
for(int p = 1; p < k; p++){
if((dp[i][j][p] && dp[i + p][j + p][k - p]) ||
(dp[i][j + k - p][p] && dp[i + p][j][k - p])){
dp[i][j][k] = true;
}
}
}
}
}
return dp[0][0][n];
}
};