97交错字符串——力扣算法系列2020.07.18 Python

本文探讨了如何使用动态规划解决LeetCode上的交错字符串验证问题。通过比较输入的三个字符串`s1`, `s2`和`s3`,确定`s3`是否由`s1`和`s2`交错组成。文章提供了详细的解题思路和Python代码实现。" 125355152,11052691,理解GRASP原则与设计模式的应用,"['设计模式', '软件构造', '面向对象设计']
摘要由CSDN通过智能技术生成

第24天
2020.07.18周六
难度系数:困难
题目:给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的。

示例 1:

输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
输出: true
示例 2:

输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
输出: false

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/interleaving-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
——————————我是分割线——————————
解法:
思路:动态规划
细心的同学们早已发现这道题目和44通配符匹配——力扣算法系列2020.07.05 Python(点击蓝色字体可查看)非常相似。

状态定义:dp[i][j]表示s1的前i个字符和s2的前j个字符是否能构成s3的前i+j个字符。
状态转移方程:dp[i][j] = (dp[i][j-1] and s2[j-1]==s3[i+j-1]) or (dp[i-1][j] and s1[i-1]==s3[i+j-1])

算法流程:
首先判断len(s1)+len(s2)是否等于len(s3),如果不等于,则一定不能构成交错字符串,返回False即可。
初始化dp为False的(len(s1)+1) * (len(s2)+1)的数组。
dp[0][0]赋值为True,只有True才可往表格右、下、右下走。
初始化第一列dp[i][0],其中i∈[1,len(s1)+1)。dp[i][0] = dp[i-1][0] and s1[i-1]==s3[i-1],其中dp[i-1][0]表示上方的格子。
初始化第一行dp[0][i],其中i∈[1,len(s2)+1)。dp[0][j] = dp[0][j-1] and s2[i-1]==s3[i-1],其中dp[0][i-1]表示左边的格子。
遍历整个dp(共i行j列,i∈[1,len(s1)+1),j∈[1,len(s2)+1))。dp[i][j] = (dp[i][j-1] and s2[j-1]==s3[i+j-1]) or (dp[i-1][j] and s1[i-1]==s3[i+j-1])
最后返回dp[-1][-1](右下角格子)即可。

以s1=“aabcc”,s2=“dbbca”,s3="aadbbcbcac"为例。
在这里插入图片描述
代码:

# leetcode97交错字符串 2020.07.18
class Solution(object):
    def isInterleave(self, s1, s2, s3):
        """
        :type s1: str
        :type s2: str
        :type s3: str
        :rtype: bool
        """
        if len(s1)+len(s2)!=len(s3): #如果s1+s2的长度不等于s3的长度 则一定不能构成交错字符串
            return False #返回False

        zong = len(s1) + 1 #纵轴长
        heng = len(s2) + 1 #横轴长
        dp = [[False]*heng for i in range(zong)] #dp数组
        dp[0][0] = True #(start,start)为True 只有T才可向右、下、右下

        for i in range(1,zong): #初始化第一列
            #dp[i-1][0]表示上方的格子
            dp[i][0] = dp[i-1][0] and s1[i-1]==s3[i-1]

        for i in range(1,heng): #初始化第一行
            #dp[0][i-1]表示左边的格子
            dp[0][i] = dp[0][i-1] and s2[i-1]==s3[i-1]

        for i in range(1,zong): #纵向 从上到下
            for j in range(1,heng): #横向 从左到右
                #s3[i+j-1]表示第i行有i个元素,第j列有j个元素 目前是s3的第i+j个元素 下标为i+j-1
                dp[i][j] = (dp[i][j-1] and s2[j-1]==s3[i+j-1]) or (dp[i-1][j] and s1[i-1]==s3[i+j-1])
        return dp[-1][-1] #最后返回右下角格子
        
s1 = "aabcc"
s2 = "dbbca"
s3 = "aadbbcbcac" #True
# s3 = "aadbbbaccc" #False
# s1 = "a"
# s2 = ""
# s3 = "a" #True
# s1 = "db"
# s2 = "b"
# s3 = "cbb" #True
print(Solution().isInterleave(s1,s2,s3))

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值