Description
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"
:
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"
.
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"
.
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
Solution
Recursion
这道题还是比较好理解的,将string表示成一棵树的形状,然后迭代交换non-leaf节点的两个子节点,看是否能得到另外一个string。
需要注意的是,题目中的树构造方式只是一个例子,"we may represent it as a binary tree by partitioning it to two non-empty substrings recursively."指的是我们可以将string按照任何比例分开。假设string s的长度为5,我们可以将其分成(1, 4), (2, 3), (3, 2), (4, 1)这几种方式。
class Solution {
public boolean isScramble(String s1, String s2) {
if (s1 == null || s2 == null || s1.length() != s2.length() || s1.isEmpty()) {
return false;
}
return isScrambleRecur(s1, s2);
}
public boolean isScrambleRecur(String s1, String s2) {
if (s1.equals(s2)) {
return true;
}
// calculate character freq in advance to prune
Map<Character, Integer> map = new HashMap<>();
for (int i = 0; i < s1.length(); ++i) {
char c = s1.charAt(i);
map.put(c, map.getOrDefault(c, 0) + 1);
}
for (int i = 0; i < s2.length(); ++i) {
char c = s2.charAt(i);
if (map.getOrDefault(c, 0) == 0) {
return false;
}
map.put(c, map.get(c) - 1);
}
int len = s1.length();
for (int l = 1; l < s1.length(); ++l) {
if ((isScrambleRecur(s1.substring(0, l), s2.substring(0, l))
&& isScrambleRecur(s1.substring(l), s2.substring(l)))
|| (isScrambleRecur(s1.substring(0, l), s2.substring(len - l))
&& isScrambleRecur(s1.substring(l), s2.substring(0, len - l)))) {
return true;
}
}
return false;
}
}