(力扣每日一题)交错字符串

交错字符串

给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的。
(力扣每日一题)交错字符串_第1张图片

解题思路
动态规划(来源力扣)
(1)开数组
我们使用dp[i][j]表示s1的前i个字符和s2的前j个字符是否能构成s3的前i+j个字符。
首先,dp[0][0]一定是True。
(2)初始化
1、初始化s1,s2,s3的长度分别为len1,len2,len3
2、若len1+len2!=len3,表示一定不能构成交错字符串,返回False
3、初始化dp为(len1+1)*(len2+1)的False数组。
(3)状态转移方程
1、初始化第一列dp[i][0],遍历第一列,遍历区间[1,len1+1):
dp[i][0]=dp[i-1][0] and s1[i-1]==s3[i-1]
表示s1的前i位是否能构成s3的前i位。因此需要满足的条件为,前i-1位可以构成s3的前i-1位,且s1的第i位(s1[i-1])等于s3的第i位(s3[i-1])

2、初始化第一行dp[0][j],遍历第一行,遍历区间[1,len2+1):
dp[0][i]=dp[0][i-1] and s2[i-1]==s3[i-1]
表示s2的前ii位是否能构成s3的前ii位。因此需要满足的条件为,前i−1位可以构成s3的前i−1位且s2的第i位(s2[i−1])等于s3的第i位(s3[i-1])

3、遍历dp数组,每一行i,遍历区间[1,len1+1):每一列j,遍历区间[1,len2+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])
解释:s1前i位和s2的前j位能否组成s3的前i+j位取决于两种情况:
s1的前i个字符和s2的前j-1个字符能否构成s3的前i+j-1位,且s2的第j位(s2[j-1])是否等于s3的第i+j位(s3[i+j-1])。

(4)、返回dp[-1][-1]

class Solution:
    def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
       #开数组
        len1=len(s1)
        len2=len(s2)
        len3=len(s3)
        if(len1+len2!=len3):
            return False
        dp=[[False]*(len2+1) for i in range(len1+1)]
        dp[0][0]=True
       #初始化第一列dp[i][0],遍历第一列,遍历区间[1,len1+1)
        for i in range(1,len1+1):
            dp[i][0]=(dp[i-1][0] and s1[i-1]==s3[i-1])
      # 初始化第一行dp[0][j],遍历第一行,遍历区间[1,len2+1)
        for i in range(1,len2+1):
            dp[0][i]=(dp[0][i-1] and s2[i-1]==s3[i-1])
       #遍历dp数组,每一行i,遍历区间[1,len1+1):每一列j,遍历区间[1,len2+1):
        for i in range(1,len1+1):
            for j in range(1,len2+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]

时间复杂度:O(mn),m为s1的长度,n为s2的长度。
空间复杂度:O(m
n)

你可能感兴趣的:(常见算法题归纳)