题目描述
给出一个字符串,建立一个二叉树用于存储它,除了叶子节点,其他节点的左右孩子都是非空子树。如下图
我们采用以下方法打乱此树:从这棵树中选择一个非叶子节点,例如gr节点,我们交换它的左右子树得到新节点”rg”。向上合并得到新的字符串:
我们说”rgeat”是”great”的乱序字符串。
问题: 给定两个同等长度字符串s1和s2,判断s2是不是s1的乱序字符串。
解决方案
1.递归版
python
class Solution:
def isScramble(self, s1, s2):
"""
:type s1: str
:type s2: str
:rtype: bool
"""
if len(s1) != len(s2): return False
if s1 == s2: return True
t1,t2 = s1,s2
if sorted(t1) != sorted(t2): return False
for i in range(1,len(s1)):
s11 = s1[:i]
s12 = s1[i:]
s21 = s2[:i]
s22 = s2[i:]
if self.isScramble(s11,s21) and self.isScramble(s12,s22): return True
s21 = s2[:len(s2)-len(s11)]
s22 = s2[len(s2)-len(s11):]
if self.isScramble(s11,s22) and self.isScramble(s12,s21): return True
return False
2. DP版,非递归
时间复杂度O(N^4)。我们引入一个布尔矩阵isS[len][i][j],表示字符串s1[i…i+len-1]是字符串s2[j…j+len-1]的乱序字符串
class Solution {
public:
bool isScramble(string s1, string s2) {
int sSize = s1.size(), len, i, j, k;
if(0==sSize) return true;
if(1==sSize) return s1==s2;
bool isS[sSize+1][sSize][sSize];
for(i=0; i<sSize; ++i)
for(j=0; j<sSize; ++j)
isS[1][i][j] = s1[i] == s2[j];
for(len=2; len <=sSize; ++len)
for(i=0; i<=sSize-len; ++i)
for(j=0; j<=sSize-len; ++j)
{
isS[len][i][j] = false;
for(k=1; k<len && !isS[len][i][j]; ++k)
{
isS[len][i][j] = isS[len][i][j] || (isS[k][i][j] && isS[len-k][i+k][j+k]);
isS[len][i][j] = isS[len][i][j] || (isS[k][i+len-k][j] && isS[len-k][i][j+k]);
}
}
return isS[sSize][0][0];
}
};