【leetcode】97. 交错字符串(interleaving-string)(DP)[困难]

215 篇文章 0 订阅
26 篇文章 0 订阅

链接

https://leetcode-cn.com/problems/interleaving-string/

耗时

解题:1 h 11 min
题解:24 min

题意

给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的。

思路

dp[i][j] 表示 s3 的前 i+j 个字符 是否是由 s1 的前 i 个字符 和 s2 的前 j 个字符 交错组成的。
那么可以分为两种情况,

  1. s3 的第 i+j 个字符 是 s1 的第 i 个字符,s3 的前 i+j-1 个字符 是由 s1 的前 i-1 个字符 和 s2 的前 j 个字符 交错组成的。
  2. s3 的第 i+j 个字符 是 s2 的第 j 个字符,s3 的前 i+j-1 个字符 是由 s1 的前 i 个字符 和 s2 的前 j-1 个字符 交错组成的。

以上两种情况只要有一种成立,即可说明 dp[i][j] 为 true。

状态转移方程:
d p [ i ] [ j ] =         ( s 1 [ i − 1 ] = = s 3 [ i + j − 1 ]   & &   d p [ i − 1 ] [ j ] )                       ∣ ∣   ( s 2 [ j − 1 ] = = s 3 [ i + j − 1 ]   & &   d p [ i ] [ j − 1 ] ) dp[i][j] = \ \ \ \ \ \ \ (s1[i-1] == s3[i+j-1] \ \&\& \ dp[i-1][j]) \\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ || \ (s2[j-1] == s3[i+j-1] \ \&\& \ dp[i][j-1]) dp[i][j]=       (s1[i1]==s3[i+j1] && dp[i1][j])                      (s2[j1]==s3[i+j1] && dp[i][j1])

细节:初始化时直接将所有 dp[i][j] 设为 false。dp[i][0] 需要提前处理,即不使用 s2, s3 的前 i 个字符 是否是由 s1 的前 i 个字符组成的,dp[0][j] 同理。

时间复杂度: O ( n m ) O(nm) O(nm),n 是 s1 的长度,m 是 s2 的长度。

AC代码

class Solution {
public:
    bool isInterleave(string s1, string s2, string s3) {
        if(s3.size() != s1.size()+s2.size()) return false;
        if(s1.size() == 0 || s2.size() == 0) return s3 == s1 || s3 == s2; 
        
        vector<vector<bool>> dp(s1.size()+1, vector<bool>(s2.size()+1, false));

        for(int i = 1; i <= s1.size(); ++i) {
            if(s1[i-1] != s3[i-1]) break;
            dp[i][0] = true;
        }
        for(int j = 1; j <= s2.size(); ++j) {
            if(s2[j-1] != s3[j-1]) break;
            dp[0][j] = true;
        }
        
        for(int i = 1; i <= s1.size(); ++i) {
            for(int j = 1; j <= s2.size(); ++j) {
                dp[i][j] = (s1[i-1] == s3[i+j-1] && dp[i-1][j]) || (s2[j-1] == s3[i+j-1] && dp[i][j-1]);
            }    
        }

        return dp[s1.size()][s2.size()];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值