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.
state:dp[i][j][len]
这道题我们维护一个三维动态规划量dp[i][j][len] 其中i为s1的起始位置, j为s2的起始位置, len为长度
dp[i][j][len]表示s1从i位到i+ len位置 与 s2从j位到j+len位是否是Scramble String
初始化:dp[i][j][1] = s1.charAt(i) == s2.charAt(j) 如果s1的i位与s2的j位字母相同 则为true
function: dp[i][j][len] = dp[i][j][l] && dp[i + l][j + l][len - l] || dp[i][j + len - l][l] && dp[i + l] [j][len - l]
有两种情况为true:
1. 存在着一点k (0 < k < len)使得s1.substring(i, i+k) 和 s2.substring(j, j+k) 为Scramble String s1.substing(i + k, i +len), s2.substring(j +k, j + len)为Scramble String 就是说s1左边的substring和s2左边的substirng s1右边的substring 和s2右边的substring 为Scramble String
2. 存在着一点k (0 < k < len)使得s1.substring(i, i+k) 和 s2.substring(j +len - k, j + len) 为Scramble String s1.substing(i+k, i +len), s2.substring(j, j + len - k)为Scramble String 就是说s1左边的substring和s2右边的substirng s1右边的substring 和s2左边的substring 为Scramble String
return: dp[0][0][n]
时间O(n^4) 空间 O(n^3)public class Solution {
public boolean isScramble(String s1, String s2) {
if (s1 == null || s2 == null || s1.length() != s2.length()) {
return false;
}
if (s1.equals(s2)) {
return true;
}
int n = s1.length();
boolean[][][] dp = new boolean[n][n][n + 1];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
dp[i][j][1] = s1.charAt(i) == s2.charAt(j);
}
}
for (int i = n - 1; i >= 0; i--) {
for (int j = n - 1; j >= 0; j--) {
for (int len = 1; len <= n - Math.max(i, j); len++) {
for (int l = 1; l < len; l++) {
if (dp[i][j][l] && dp[i + l][j + l][len - l] || dp[i][j + len - l][l] && dp[i + l] [j][len - l]) {
dp[i][j][len] = true;
break;
}
}
// }
}
}
}
return dp[0][0][n];
}
}
没有评论:
发表评论