We can scramble a string s to get a string t using the following algorithm:
Dynamic Programming (DP).
State Define: f ( L 1 , L 2 , L L ) f(L1, L2, LL) f(L1,L2,LL) is the state that if s 1 [ L 1 , L 1 + L L ] s1[L1,L1+LL] s1[L1,L1+LL] matches s 2 [ L 2 , L 2 + L L ] s2[L2,L2+LL] s2[L2,L2+LL].
Transform: f ( L 1 , L 2 , L L ) = m a x ( f ( L 1 , L 2 , k ) & f ( L 1 + k , L 2 + k , L L − k ) , f ( L 1 + L L − k , L 2 , k ) & f ( L 1 , L 2 + k , L L − k ) ) f(L1, L2, LL) = max(f(L1, L2, k) \& f(L1+k,L2+k, LL-k), f(L1+LL-k, L2, k) \& f(L1,L2+k, LL-k)) f(L1,L2,LL)=max(f(L1,L2,k)&f(L1+k,L2+k,LL−k),f(L1+LL−k,L2,k)&f(L1,L2+k,LL−k)) where k ∈ [ 1 , L L ] k \in [1, LL] k∈[1,LL].
class Solution:
def isScramble(self, s1: str, s2: str) -> bool:
ls1 = len(s1)
ls2 = len(s2)
if ls1 != ls2:
return False
if ls1 == 0:
return True
dp = [[[0] * (ls1+1) for j in range(ls1+1)] for k in range(ls1+1)]
# dp[L1][L2][LL] = (s1[L1:L1+LL] == s2[L2:L2+LL])
for LL in range(1, ls1+1):
for L1 in range(1, ls1+1):
R1 = L1+LL-1
if R1 > ls1:
continue
for L2 in range(1, ls2+1):
R2 = L2+LL-1
if R2 > ls2:
continue
if LL == 1:
if s1[L1-1] == s2[L2-1]:
dp[1][L1][L2] = 1
else:
for k in range(1, LL):
if dp[k][L1][L2] and dp[LL-k][L1+k][L2+k]:
dp[LL][L1][L2] = 1
break
if dp[k][L1+LL-k][L2] and dp[LL-k][L1][L2+k]:
dp[LL][L1][L2] = 1
break
return dp[ls1][1][1]