Leetcode 87. Scramble String

Problem

We can scramble a string s to get a string t using the following algorithm:

  1. If the length of the string is 1, stop.
  2. If the length of the string is > 1, do the following:
    • Split the string into two non-empty substrings at a random index, i.e., if the string is s, divide it to x and y where s = x + y.
    • Randomly decide to swap the two substrings or to keep them in the same order. i.e., after this step, s may become s = x + y or s = y + x.
    • Apply step 1 recursively on each of the two substrings x and y.
      Given two strings s1 and s2 of the same length, return true if s2 is a scrambled string of s1, otherwise, return false.

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,LLk),f(L1+LLk,L2,k)&f(L1,L2+k,LLk)) where k ∈ [ 1 , L L ] k \in [1, LL] k[1,LL].

Code

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]

你可能感兴趣的:(解题报告,动态规划(DP))