题目如下:
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 tTo 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 tWe 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 aWe 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: trueExample 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