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
题目求s2 是否是s1的密码串。
用递归回溯。复杂度O(l^3)。代码如下:
class Solution(object):
def isScramble(self, s1, s2):
"""
:type s1: str
:type s2: str
:rtype: bool
"""
l1 = len(s1)
l2 = len(s2)
if l1 != l2:
return False
def checkStrCharCount(s1,s2,l):#检测两个字符串字符统计是否相同
count = {}
for i in range(l):
if s1[i] in count:
count[s1[i]] += 1
else:
count[s1[i]] = 1
if s2[i] in count:
count[s2[i]] -= 1
else:
count[s2[i]] = -1
for _, val in count.items():
if val != 0:
return False
return True
if not checkStrCharCount(s1,s2,l1):
return False
tmp = {} #缓存结果
def DFS(s1,s2,size):# 深度优先
if size <= 3:
return True
key = (s1,s2)
if key in tmp:
return tmp[key]
for i in range(1,size):
if checkStrCharCount(s1[0:i], s2[0:i],i) and DFS(s1[0:i], s2[0:i],i) and DFS(s1[i:], s2[i:],size-i):
tmp[key] = True
return True
if checkStrCharCount(s1[0:i], s2[size-i:],i) and DFS(s1[0:i], s2[size-i:],i) and DFS(s1[i:], s2[0:],size-i):
tmp[key] = True
return True
tmp[key] = False
return False
return DFS(s1,s2,l1)