87. Scramble String

  • Difficulty: Hard

  • Topics: String, Dynamic Programming

  • Similar Questions:

Problem:

Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrings recursively.

Below is one possible representation of s1 = "great":

    great
   /    \
  gr    eat
 / \    /  \
g   r  e   at
           / \
          a   t

To scramble the string, we may choose any non-leaf node and swap its two children.

For example, if we choose the node "gr" and swap its two children, it produces a scrambled string "rgeat".

    rgeat
   /    \
  rg    eat
 / \    /  \
r   g  e   at
           / \
          a   t

We say that "rgeat" is a scrambled string of "great".

Similarly, if we continue to swap the children of nodes "eat" and "at", it produces a scrambled string "rgtae".

    rgtae
   /    \
  rg    tae
 / \    /  \
r   g  ta  e
       / \
      t   a

We say that "rgtae" is a scrambled string of "great".

Given two strings s1 and s2 of the same length, determine if s2 is a scrambled string of s1.

Example 1:

Input: s1 = "great", s2 = "rgeat"
Output: true

Example 2:

Input: s1 = "abcde", s2 = "caebd"
Output: false

Solutions:

class Solution {
public:
    bool isScramble(string s1, string s2) {
        int len1 = s1.length();
        int len2 = s2.length();

        map<vector<int>, bool> cache;
        return helper(s1, s2, 0, 0, len1, cache);
    }

    bool helper(string s1, string s2, int idx1, int idx2, int len, map<vector<int>, bool>& cache) {
        if (cache.find({idx1, idx2, len}) != cache.end()) {
            return cache[{idx1, idx2, len}];
        }

        bool ret = false;

        if (stringEqual(s1, s2, idx1, idx2, len)) {
            cache[{idx1, idx2, len}] = true;
            return true;
        }

        for (int part1 = 1; part1 <= len - 1; ++part1) {
            if (helper(s1, s2, idx1, idx2, part1, cache) && helper(s1, s2, idx1 + part1, idx2 + part1, len - part1, cache)) {
                cache[{idx1, idx2, len}] = true;
                return true;
            }

            if (helper(s1, s2, idx1, idx2 + len - part1, part1, cache) && helper(s1, s2, idx1 + part1, idx2, len - part1, cache)) {
                cache[{idx1, idx2, len}] = true;
                return true;
            }
        }

        cache[{idx1, idx2, len}] = false;
        return false;
    }

    bool stringEqual(string s1, string s2, int idx1, int idx2, int len) {
        if (idx1 + len > s1.length())   return false;
        if (idx2 + len > s2.length())   return false;

        for (int i = 0; i < len; ++i) {
            if (s1[i + idx1] != s2[i + idx2]) return false;
        }

        return true;
    }   
};

results matching ""

    No results matching ""