【leetcode】87. Scramble String

题目如下:

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.

Example 1:

Input: s1 = "great", s2 = "rgeat"
Output: true

Example 2:

Input: s1 = "abcde", s2 = "caebd"
Output: false

解题思路:本题的关键在于怎么把s1分解成树的结构,这里千万不要被Example 1的分割示例误导,以为只能是对半分,实际上是分割成任意长度的。例如s1="hobobyrqd",分给左边子节点的子串可以是"h","ho","hob"... "hobobyrq";假如左边子节点分到的是"hob",那么继续分割"hob"成两部分分别给左边子节点的左右子节点,看到这里,应该已经猜到本题采用递归了。对的,就是递归。注意,在分割的过程中要剪枝,例如s1="hobobyrqd",s2 = "hbyorqdbo" ,如果s1分成"hob"和"obyrqd"两段,那么s2也可以分成包括相同字母的两段(只需要包括的字母相同,不用考虑顺序,因为后续子节点还能交换),如果不可以则表示这种拆分方式不行。

代码如下:

class Solution(object):
    def isScramble(self, s1, s2):
        """
        :type s1: str
        :type s2: str
        :rtype: bool
        """
        if s1 == s2:
            return True
        s1_sub = []
        s2_sub = []
        for div in range(1,len(s1)):
            s1_sub.append((s1[:div],s1[div:]))
            s2_sub.append((s2[:div], s2[div:]))

        for i1,i2 in s1_sub:
            for j1,j2 in s2_sub:
                if sorted(list(i1)) == sorted(list(j1)) and sorted(list(i2)) == sorted(list(j2)):
                    #print i1,j1,i2,j2
                    if self.isScramble(i1, j1) and self.isScramble(i2, j2) == True:
                        return True
                elif sorted(list(i1)) == sorted(list(j2)) and sorted(list(i2)) == sorted(list(j1)):
                    #print i1, j2, i2, j1
                    if  self.isScramble(i1, j2) and self.isScramble(i2, j1) == True:
                        return True
        return False
原文地址:https://www.cnblogs.com/seyjs/p/10218915.html