87. Scramble String
可以拼凑的字符串,题目比较拗口大概意思是说一个字符串可以分解成各种形状的叶节点为字符的二叉树,现在s1,s2两个字符串,将s1分解的到的二叉树中任意结点的左右子树互换叫做一次操作,如果通过若干次这样的操作s1可以变为s2,那么就把s1称作s2的可拼凑字符串.
很显然如果s1是s2的可拼凑字符串,那么s2也是s1的可拼凑字符串.
进一步分析这个题目,如果将s1分成两部分s11,s22; s2也分成两部分:s21,s22.如果s11和s21拼凑,s12和s22可拼凑,那么s1和s2也是可拼凑的;或者说s12和s21可拼凑,s11和s22可拼凑也能得到该结论.
class Solution: # def __init__(self): # self.ScrambleSet = set() def isScramble(self, s1: str, s2: str) -> bool: if sorted(s1) != sorted(s2): return False if s1 == s2: return True length = len(s1) # if(s1, s2) in self.ScrambleSet: # return True for i in range(1,length): s11, s12 = s1[0:i], s1[i:] s21, s22 = s2[0:i], s2[i:] s23, s24 = s2[0:length-i], s2[length-i:] if self.isScramble(s11, s21) and self.isScramble(s12, s22): return True if self.isScramble(s11, s24) and self.isScramble(s12, s23): return True return False
这种方法用到了递归;或者换一种角度思考可以用动态规划来解决,同样的思路,我们需要知道的是子字符串能否拼凑,需要的参数有子字符串长度,子字符串开始的位置,因为有两个字符串所以是三个参数:k,i,j:k对应子字符串长,i是s1中子字符串的开始位置,j是s2中子字符串的开始位置
class Solution: def getisScrambleMatrix(self, length, s1, s2, resultmatrix): for i in range(length): for j in range(length): if s1[i] == s2[j]: resultmatrix[1][i][j] = True else: resultmatrix[1][i][j] = False #子字符串长度是k for k in range(2, length+1): for i in range(length-k+1): for j in range(length-k+1): if sorted(s1[i:i+k]) != sorted(s2[j:j+k]): resultmatrix[k][i][j] = False else: #m是s1截取的前半段字符串长度 for m in range(1, k): if (resultmatrix[m][i][j] and resultmatrix[k-m][i+m][j+m]) or(resultmatrix[m][i][j+k-m] and resultmatrix[k-m][i+m][j]): resultmatrix[k][i][j] = True break else: resultmatrix[k][i][j] = False def isScramble(self, s1: str, s2: str) -> bool: len_1, len_2 = len(s1), len(s2) if len_1 != len_2: return False if sorted(s1) != sorted(s2): return False #k对应子字符串长,i是s1中子字符串的开始位置,j是s2中子字符串的开始位置 resultmatrix = [[[None for j in range(len_2)] for i in range(len_1)] for k in range(len_1+1)] self.getisScrambleMatrix(len_1, s1, s2, resultmatrix) return resultmatrix[len_1][0][0]