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

题目

给定三个字符串 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> dp(n1+1, vector(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];
    }
};

你可能感兴趣的:(leetcode,算法,动态规划)