Skip to content

87. Scramble String

  • Time:
  • Space:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution {
 public:
  bool isScramble(string s1, string s2) {
    if (s1 == s2)
      return true;
    if (s1.length() != s2.length())
      return false;
    const string hashedKey = s1 + '+' + s2;
    if (memo.count(hashedKey))
      return memo[hashedKey];

    vector<int> count(128);

    for (int i = 0; i < s1.length(); ++i) {
      ++count[s1[i]];
      --count[s2[i]];
    }

    if (any_of(begin(count), end(count), [](int c) { return c != 0; }))
      return memo[hashedKey] = false;

    for (int i = 1; i < s1.length(); ++i) {
      if (isScramble(s1.substr(0, i), s2.substr(0, i)) &&
          isScramble(s1.substr(i), s2.substr(i)))
        return memo[hashedKey] = true;
      if (isScramble(s1.substr(0, i), s2.substr(s2.length() - i)) &&
          isScramble(s1.substr(i), s2.substr(0, s2.length() - i)))
        return memo[hashedKey] = true;
    }

    return memo[hashedKey] = false;
  }

 private:
  unordered_map<string, bool> memo;
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Solution {
  public boolean isScramble(String s1, String s2) {
    if (s1.equals(s2))
      return true;
    if (s1.length() != s2.length())
      return false;
    final String hashedKey = s1 + "+" + s2;
    if (memo.containsKey(hashedKey))
      return memo.get(hashedKey);

    int[] count = new int[128];

    for (int i = 0; i < s1.length(); ++i) {
      ++count[s1.charAt(i)];
      --count[s2.charAt(i)];
    }

    for (final int c : count)
      if (c != 0) {
        memo.put(hashedKey, false);
        return false;
      }

    for (int i = 1; i < s1.length(); ++i) {
      if (isScramble(s1.substring(0, i), s2.substring(0, i)) &&
          isScramble(s1.substring(i), s2.substring(i))) {
        memo.put(hashedKey, true);
        return true;
      }
      if (isScramble(s1.substring(0, i), s2.substring(s2.length() - i)) &&
          isScramble(s1.substring(i), s2.substring(0, s2.length() - i))) {
        memo.put(hashedKey, true);
        return true;
      }
    }

    memo.put(hashedKey, false);
    return false;
  }

  private Map<String, Boolean> memo = new HashMap<>();
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class Solution:
  def isScramble(self, s1: str, s2: str) -> bool:
    if s1 == s2:
      return True
    if len(s1) != len(s2):
      return False
    if Counter(s1) != Counter(s2):
      return False

    for i in range(1, len(s1)):
      if self.isScramble(s1[:i], s2[:i]) and self.isScramble(s1[i:], s2[i:]):
        return True
      if self.isScramble(s1[:i], s2[len(s2) - i:]) and self.isScramble(s1[i:], s2[:len(s2) - i]):
        return True

    return False