• leetcode 97. Interleaving String


    Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.

    For example,
    Given:
    s1 = "aabcc",
    s2 = "dbbca",
    
    When s3 = "aadbbcbcac", return true.
    When s3 = "aadbbbaccc", return false.
    

    第一个思路肯定可能就是递归了

    class Solution {
    public:
        int mark = 0;
        void dfs(string& s1, string& s2, string& s3, int a, int b, int c) {
            if (c == s3.size() && a == s1.size() && b == s2.size()) {
                mark = 1;
                return;
            }
            for (int i = c; i < s3.size(); ++i) {
                if (s1[a] == s3[c]) {
                    dfs(s1, s2, s3, a+1, b, c+1);
                }
                if (s2[b] == s3[c]) {
                    dfs(s1, s2, s3, a, b+1, c+1);
                }
            }
        }
        bool isInterleave(string s1, string s2, string s3) {
            dfs(s1, s2, s3, 0, 0, 0);
            if (mark) return true;
            return false;
        }
        
    };
    

    但是这样会超时,时间复杂度最坏将近O(n^3) 所以采用dp的方法,能降到O(n^2)的时间复杂度。那么如何dp呢?其实很简单啦
    构造一个匹配矩阵,ForExample
    1
    可以想象,向右走代表匹配s1[i]和s3[k]向下走代表匹配s2[j]和s3[k],如果能匹配上就记1,那么如果dp[n][m]为1就代表能匹配上。上图给出了一个匹配路径。
    那么转移方程如下:
    dp[i][j]=dp[i-1][j]&(s1[i]==s3[i+j-1])|(dp[i][j-1]&(s2[j]==s3[i+j-1])
    代码如下:

    class Solution {
    public:
        
        bool isInterleave(string s1, string s2, string s3) {
            int n = s1.size();
            int m = s2.size();
            vector<vector<int> > dp(n+1, vector<int>(m+1, 0));
            dp[0][0] = 1;
            if (s3.size() != n + m) return false;
            if (n == 0) {
                if (s3 == s2) return true;
                return false;
            }
            if (m == 0) {
                if (s1 == s3) return true;
                return false;
            }
            for (int i = 0; i <= n; ++i) {
                for (int j = 0; j <= m; ++j) {
                    if (i == 0 && j == 0) continue;
                    else if (i == 0) dp[i][j] = dp[i][j-1] & (s2[j-1] == s3[i+j-1]);
                    else if (j == 0) dp[i][j] = dp[i-1][j] & (s1[i-1] == s3[i+j-1]);
                    else  dp[i][j] = (dp[i][j-1] & (s2[j-1] == s3[i+j-1])) | (dp[i-1][j] & (s1[i-1] == s3[i+j-1]));
                }
            }
            return dp[n][m];
        }
        
    };
    
  • 相关阅读:
    luogu P5494 【模板】线段树分裂
    珂朵莉树(ODT)
    luogu P5787 二分图 /【模板】线段树分治
    线段树
    luogu P1450 [HAOI2008]硬币购物
    树形DP
    luogu P3047 [USACO12FEB]Nearby Cows G
    1069: 向Z同学学习
    1067: 有问题的里程表
    1066: 字符分类统计
  • 原文地址:https://www.cnblogs.com/pk28/p/8146612.html
Copyright © 2020-2023  润新知