import java.util.HashMap;
import java.util.Map;
class Solution {
public static void main(String[] args) {
Solution solution = new Solution();
boolean res = solution.isScramble("eebaacbcbcadaaedceaaacadccd", "eadcaacabaddaceacbceaabeccd");
System.out.println(res);
}
public boolean isScramble(String s1, String s2) {
return isRaoluanStr(s1, s2);
}
public boolean isSame(String s1, int from1, String s2, int from2, int len) {
int[] arr = new int[26];
for (int i = 0; i < len; i++) {
arr[s1.charAt(from1 + i) - 'a']++;
arr[s2.charAt(from2 + i) - 'a']--;
}
for (int i = 0; i < len; i++) {
if (arr[s1.charAt(from1 + i) - 'a'] != 0) {
return false;
}
if (arr[s2.charAt(from2 + i) - 'a'] != 0) {
return false;
}
}
return true;
}
public boolean isEqual(String s1, String s2, int splitIndex) {
return isSame(s1, 0, s2, 0, splitIndex + 1)
&& isSame(s1, splitIndex + 1, s2, splitIndex + 1, s1.length() - splitIndex - 1);
}
public boolean isYxSame(String s1, String s2, int splitIndex) {
// s1 y,x
int n = s1.length();
int xlen = splitIndex + 1;
int ylen = n - xlen;
String y = s1.substring(n - ylen);
String x = s1.substring(0, xlen);
// s2 x,y
String x1 = s2.substring(0, ylen);
String y1 = s2.substring(ylen);
return isSame(y, 0, x1, 0, ylen) && isSame(x, 0, y1, 0, xlen);
}
Map<String,Map<String,Boolean>> map = new HashMap<>();
public boolean isRaoluanStr(String s1, String s2) {
if (s1.length() != s2.length()) {
return false;
}
if (s1.length() == 1) {
if (s1.charAt(0) == s2.charAt(0)) {
return true;
}
return false;
}
if (map.get(s1) != null && map.get(s1).get(s2) != null) {
return map.get(s1).get(s2);
}
// 分割
boolean ans = false;
int n = s1.length();
for (int split = 0; split < n - 1; split++) {
if (isEqual(s1, s2, split)) {
// 可以切割s1, s2;
ans |= isRaoluanStr(s1.substring(0, split + 1), s2.substring(0, split + 1))
&& isRaoluanStr(s1.substring(split + 1), s2.substring(split + 1));
if (ans) {
break;
}
}
if (isYxSame(s1, s2, split)) {
ans |= isRaoluanStr(s1.substring(split + 1), s2.substring(0, s1.length() - split - 1))
&& isRaoluanStr(s1.substring(0, split + 1), s2.substring(s1.length() - split - 1));
if (ans) {
break;
}
}
}
map.put(s1, map.getOrDefault(s1,new HashMap<>()));
map.get(s1).put(s2, ans);
map.put(s2, map.getOrDefault(s2, new HashMap<>()));
map.get(s2).put(s1, ans);
return ans;
}
}