zoukankan      html  css  js  c++  java
  • 87.扰乱字符串

    class Solution:
        def isScramble(self, s1: str, s2: str) -> bool:
            # DP 难点分析:
            # 1.首先理解三层DP分别代表:长度,s1起点,s2起点
            # 2.初始化DP长度为1的DP子串
            # 3.状态转移方程,长度为l的dp[l]可以从dp[l-k] 与 dp[k] 转移而来
            # 4.DP种几层端点的选择
            #   1) 对于len是有实际意义的,不能为0,并且初始化时遍历了1,所以其取值为 range(2,lens+1)
            #   2)  对于端点都是从index = 0开始的,但是要保证index+l <=lens;
            #       比如 lens = 10, l = 8(包括i的8个数) ,i = 0,1,2 = range(lens-l+1)
            #   3) 对于分隔符号k,取值范围为 1,l-1 因为 = range(1,l)
    
            if sorted(s1)!=sorted(s2):
                return False
            if s1==s2:
                return True
            lens = len(s1)
            dp = [[[False]*(lens) for _ in range(lens)]for _a in range(lens+1)]
            for i in range(lens):
                for j in range(lens):
                    dp[1][i][j] = s1[i] == s2[j] 
    
            for l in range(2,lens+1):
                for i in range(lens-l+1):
                    for j in range(lens-l+1):
                        for k in range(1,l+1):
                            # 如果 l = 8, k = 2
                            # 没有扰乱 s1 = i:i+2 ,i+2,i+8
                            #         s2 = j:j+k, j+k:j+l
                            if dp[k][i][j] and dp[l-k][i+k][j+k]:
                                dp[l][i][j] = True
                                break
                            # 扰乱   s2  = j+l-k:j+l , j:j+l-k
                            if dp[k][i][j+l-k] and dp[l-k][i+k][j]:
                                dp[l][i][j] = True
                                break
            return dp[lens][0][0]
    
    
    
            # 递归,
            # basecase: 两字符串相等 返回true    
            # 上层:     对于每一个切分点,如果对应段相等,或者交叉相等,则返回True
    
    
            # if sorted(s1) != sorted(s2):return False
            # if s1 == s2 :return True
    
            # for i in range(1,len(s1)):
            #     s11,s12 = s1[:i],s1[i:]
            #     # 正向切s2 比如长度为8 i=1分成1,7
            #     s21,s22 = s2[:i],s2[i:]
            #     if self.isScramble(s11,s21) and self.isScramble(s12,s22):
            #         return True
            #     # 反向切s2 比如长度为8 i=1分成7,1
            #     s21,s22 = s2[:len(s1)-i],s2[len(s1)-i:]
            #     if self.isScramble(s11,s22) and self.isScramble(s12,s21):
            #         return True
            # return False
    

      

    class Solution:
        def isScramble(self, s1: str, s2: str) -> bool:
            # DP 难点分析:
            # 1.首先理解三层DP分别代表:长度,s1起点,s2起点
            # 2.初始化DP长度为1的DP子串
            # 3.状态转移方程,长度为l的dp[l]可以从dp[l-k] 与 dp[k] 转移而来
            # 4.DP种几层端点的选择
            #   1) 对于len是有实际意义的,不能为0,并且初始化时遍历了1,所以其取值为 range(2,lens+1)
            #   2)  对于端点都是从index = 0开始的,但是要保证index+l <=lens;
            #       比如 lens = 10, l = 8(包括i的8个数) ,i = 0,1,2 = range(lens-l+1)
            #   3) 对于分隔符号k,取值范围为 1,l-1 因为 = range(1,l)

            if sorted(s1)!=sorted(s2):
                return False
            if s1==s2:
                return True
            lens = len(s1)
            dp = [[[False]*(lens) for _ in range(lens)]for _a in range(lens+1)]
            for i in range(lens):
                for j in range(lens):
                    dp[1][i][j] = s1[i] == s2[j] 

            for l in range(2,lens+1):
                for i in range(lens-l+1):
                    for j in range(lens-l+1):
                        for k in range(1,l+1):
                            # 如果 l = 8, k = 2
                            # 没有扰乱 s1 = i:i+2 ,i+2,i+8
                            #         s2 = j:j+k, j+k:j+l
                            if dp[k][i][j] and dp[l-k][i+k][j+k]:
                                dp[l][i][j] = True
                                break
                            # 扰乱   s2  = j+l-k:j+l , j:j+l-k
                            if dp[k][i][j+l-k] and dp[l-k][i+k][j]:
                                dp[l][i][j] = True
                                break
            return dp[lens][0][0]



            # 递归,
            # basecase: 两字符串相等 返回true    
            # 上层:     对于每一个切分点,如果对应段相等,或者交叉相等,则返回True


            # if sorted(s1) != sorted(s2):return False
            # if s1 == s2 :return True

            # for i in range(1,len(s1)):
            #     s11,s12 = s1[:i],s1[i:]
            #     # 正向切s2 比如长度为8 i=1分成1,7
            #     s21,s22 = s2[:i],s2[i:]
            #     if self.isScramble(s11,s21) and self.isScramble(s12,s22):
            #         return True
            #     # 反向切s2 比如长度为8 i=1分成7,1
            #     s21,s22 = s2[:len(s1)-i],s2[len(s1)-i:]
            #     if self.isScramble(s11,s22) and self.isScramble(s12,s21):
            #         return True
            # return False
  • 相关阅读:
    第三周psp
    作业2
    词频统计 SPEC 20170914 1 1 1 1 1
    psp1111
    第一周大作业1
    mongodb安装操作 (2018/11/12)
    中间件 express生成项目(2018/11/10)
    express环境搭建(2018/11/09)
    后端路由(2018/11/07)
    Node模块的基本使用(2018/11/06)
  • 原文地址:https://www.cnblogs.com/ChevisZhang/p/14137752.html
Copyright © 2011-2022 走看看