87. Scramble String打乱字符串

题目描述

给出一个字符串,建立一个二叉树用于存储它,除了叶子节点,其他节点的左右孩子都是非空子树。如下图
二叉树
我们采用以下方法打乱此树:从这棵树中选择一个非叶子节点,例如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];            

    }
}; 

猜你喜欢

转载自blog.csdn.net/fegnkuang/article/details/81629288