题目分析:
这个题目比较难理解,说是给定一个字符串 s1,我们可以把它递归地分割成两个非空子字符串,从而将其表示为二叉树。下图是字符串 s1 = “great” 的一种可能的表示形式。
在扰乱这个字符串的过程中,我们可以挑选任何一个非叶节点,然后交换它的两个子节点。例如,如果我们挑选非叶节点 “gr” ,交换它的两个子节点,将会产生扰乱字符串 “rgeat” 。
我们将 "rgeat” 称作 “great” 的一个扰乱字符串。
同样地,如果我们继续先将其节点 “eat” ,再其节点 “at” 进行交换,将会产生另一个新的扰乱字符串 “rgtae” 。
我们将 "rgtae” 称作 “great” 的一个扰乱字符串。
给我们两个长度相等的字符串 s1 和 s2,判断 s2 是否是 s1 的扰乱字符串。
解题思路:
我们吧这个题目划归为小问题,只有两个。
(1)对应位相等(2)互相交换位置相等
如"rgeat” 和 “great”,rg和gr属于(2),eat和eat属于*(1)*,那么我们就可以写成递归来不停的划分字串进行判断。
循环划分位数
- 划分一位,比较前后,后面的再划分进入递归,不行就退出
- 划分两位,比较前后,进入递归,不行就退出
- … …
上面的 (1),(2) 是核心思路,实现为代码就是:
if self.isScramble(s1[: i], s2[: i]) and self.isScramble(s1[i:], s2[i:]): return True
if self.isScramble(s1[: i], s2[length - i:]) and self.isScramble(s1[i:], s2[: length - i]): return True
测试代码:(Runtime: 52 ms, faster than 80.15% )
class Solution:
def isScramble(self, s1, s2):
if s1 == s2: return True
if sorted(list(s1)) != sorted(list(s2)): return False
length = len(s1)
for i in range(1, length):
if self.isScramble(s1[: i], s2[: i]) and self.isScramble(s1[i:], s2[i:]): return True
if self.isScramble(s1[: i], s2[length - i:]) and self.isScramble(s1[i:], s2[: length - i]): return True
return False
print(Solution().isScramble(s1 = "great", s2 = "rgtae")) #提交时请删除该行
附:
这个题目动态规划应该也是可以实现的,因为像aab与aac其中的aa可以保存结果用于后续判断。之后我可能会进行思考并补充。