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.
解法:三维动态规划,f(i,j,l)表示s1从下标j开始长l的字符串和s2从j开始长l的字符串是否可以转换。则有
f(i,j,l) = f(i,j,k) && f(i+k,j+k,l-k) || f(i,j+l-k,k)&& f(i+l-k,j,l-k). 初始化:l = 1;返回f[0][0][S1.length()-1]
代码如下:
class Solution {
public:
bool isScramble(string s1, string s2) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
if(s1.length() != s2.length()) return false;
if(s1.length() == 0 || s1 == s2) return true;
int n = s1.length();
bool f[n][n][n];
for(int i = 0;i < n;i++)
{
for(int j = 0;j < n;j++)
{
f[i][j][0] = (s1[i] == s2[j])?true:false;
}
}
for(int l = 2;l <= n;l++)
{
for(int i = 0;i <= n - l;i++)
{
for(int j = 0;j <= n - l;j++)
{
f[i][j][l-1] = false;
for(int k = 1;k<l;k++)
{
if(f[i][j][k-1]&&f[i+k][j+k][l-k-1] ||
f[i][j+l-k][k-1]&& f[i+k][j][l-k-1]) {
f[i][j][l-1] = true;
break;
}
}
}
}
}
return f[0][0][n-1];
}
};
52 milli secs.