力扣_字符串7—交错字符串

文章讨论了如何利用动态规划算法判断三个字符串s1、s2和s3是否可以通过交替子串的方式形成。方法涉及构建一个布尔矩阵来存储子问题的解,空间复杂度通过滚动数组优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

给定三个字符串 s 1 、 s 2 、 s 3 s1、s2、s3 s1s2s3,请你帮忙验证 s 3 s3 s3 是否是由 s 1 s1 s1 s 2 s2 s2 交错 组成的。

两个字符串 s s s t t t 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空 子字符串:

  • s = s 1 + s 2 + . . . + s n s = s1 + s2 + ... + sn s=s1+s2+...+sn
  • t = t 1 + t 2 + . . . + t m t = t1 + t2 + ... + tm t=t1+t2+...+tm
  • ∣ n − m ∣ < = 1 |n - m| <= 1 nm<=1
  • 交错 是 s 1 + t 1 + s 2 + t 2 + s 3 + t 3 + . . . s1 + t1 + s2 + t2 + s3 + t3 + ... s1+t1+s2+t2+s3+t3+... 或者 t 1 + s 1 + t 2 + s 2 + t 3 + s 3 + . . . t1 + s1 + t2 + s2 + t3 + s3 + ... t1+s1+t2+s2+t3+s3+...

方法

  • 动态规划
    • s 1 、 s 2 、 s 3 s1、s2、s3 s1s2s3 长度分别为 n 1 、 n 2 、 n n1、n2、n n1n2n
    • 定义 d p n 1 + 1 , n 2 + 2 dp_{n1+1,n2+2} dpn1+1,n2+2 数组, d p [ i ] [ j ] dp[i][j] dp[i][j] 表示 s 3 s3 s3 i + j i+j i+j 个字符是否由 s 1 s1 s1 i i i 个字符和 s 2 s2 s2 j j j 个字符交错组成
    • s 3 [ i + j − 1 ] = = s 1 [ i − 1 ] s3[i+j-1] == s1[i-1] s3[i+j1]==s1[i1],则 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] dp[i][j] = dp[i-1][j] dp[i][j]=dp[i1][j]
    • s 3 [ i + j − 1 ] = = s 2 [ j − 1 ] s3[i+j-1] == s2[j-1] s3[i+j1]==s2[j1],则 d p [ i ] [ j ] = d p [ i ] [ j − 1 ] dp[i][j] = dp[i][j-1] dp[i][j]=dp[i][j1]
    • 空间复杂度优化:滚动数组
      • 定义 d p n 2 + 2 dp_{n2+2} dpn2+2 数组
      • d p [ j ] dp[j] dp[j] 上一次循环的值表示原来的 d p [ i − 1 ] [ j ] dp[i-1][j] dp[i1][j]

代码

class Solution {
public:
    // bool isInterleave(string s1, string s2, string s3) {
    //     int n1 = s1.size();
    //     int n2 = s2.size();
    //     int n = s3.size();
    //     if(n1+n2 != n)
    //         return false;
    //     vector<vector<bool>> dp(n1+1, vector<bool>(n2+1));
    //     dp[0][0] = true;
    //     for(int i = 0; i <= n1; i++){
    //         for(int j = 0; j <= n2; j++){
    //             if(i > 0){
    //                 dp[i][j] = dp[i][j] || (dp[i-1][j] && s1[i-1] == s3[i+j-1]);
    //             }
    //             if(j > 0){
    //                 dp[i][j] = dp[i][j] || (dp[i][j-1] && s2[j-1] == s3[i+j-1]);
    //             }
    //         }
    //     }
    //     return dp[n1][n2];
    // }
    bool isInterleave(string s1, string s2, string s3) {
        int n1 = s1.size();
        int n2 = s2.size();
        int n = s3.size();
        if(n1+n2 != n)
            return false;
        vector<bool> dp(n2+1);
        dp[0] = true;
        for(int i = 0; i <= n1; i++){
            for(int j = 0; j <= n2; j++){
                if(i > 0){
                    dp[j] = (dp[j] && s1[i-1] == s3[i+j-1]);
                }
                if(j > 0){
                    dp[j] = dp[j] || (dp[j-1] && s2[j-1] == s3[i+j-1]);
                }
            }
        }
        return dp[n2];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值