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.
题意:给出两个字符串s1和s2,问s2是否是s1的二叉树的打散结构表示
思路:用dp(len,i,j)表示从s1的i索引,s2的j索引开始,长度为len的子串是否是打散结构
则要么前k个字符相等或者交叉相等,所有以dp(len,i,j)=(dp(k,i,j) && dp(len - k, i + k, j + k)) || (dp(k, i, j + len - k) && (dp(len - k, i + k, j))
具体代码如下:
public class Solution
{
public boolean isScramble(String s1, String s2) {
int len1 = s1.length();
int len2 = s2.length();
if (len1 != len2) return false;
boolean[][][] dp = new boolean[len1 + 1][len1 + 1][len1 + 1];
for (int i = 0; i < len1; i++) {
for (int j = 0; j < len2; j++) {
dp[1][i][j] = s1.charAt(i) == s2.charAt(j);
}
}
for (int len = 2; len <= len1; len++) {
for (int i = 0; i <= len1 - len; i++) {
for (int j = 0; j <= len1 - len; j++) {
for (int k = 1; k < len && !dp[len][i][j]; k++) {
dp[len][i][j] = (dp[k][i][j] && dp[len - k][i + k][j + k]) || (dp[k][i + len - k][j] && dp[len - k][i][j + k]);
}
}
}
}
return dp[len1][0][0];
}
}