97. Interleaving String

来源:互联网 发布:mac itunes 铃声找不到 编辑:程序博客网 时间:2024/06/06 09:22

有两个字符串s1和s2,每次从这两个字符串中的一个中取出一个字符(从前往后取),直到两个字符串都取完,这样可以组成很多新的字符串,问s3是否属于这些新组成的字符串中的一个。问s3是不是s1和s2的交织相错的字符串。

这道题暴力解法超时了,遇到字符串子串和匹配的这种问题,可以想动态规划方法。

一般来说字符串匹配问题都是更新一个二维dp数组。下面是借鉴大神博客的分析:

dp[i][j] 表示 s2 的前 i 个字符和 s1 的前 j 个字符是否匹配 s3 的前 i+j 个字符

初始化dp[0][0]=0,dp[0][j]表示s2取0个,即s1的前j个字符是否匹配s3的前j个字符;dp[i][0]表示s1取0个,即s2的前i个字符,是否匹配s3的前i个字符。

动规方程:dp[i][j] = dp[i - 1][j] && s2[i - 1] == s3[i + j - 1]  ||  dp[i][j - 1] && s1[i][j - 1] == s3[i + j - 1] ,意思是如果s2的前i-1个字符和s1的前j个字符已经和s3的前i+j-1个字符匹配且s2的第i个字符等于s3的第i+j个字符,或者s2的前i个字符和s1的前j-1个字符已经和s3的前i+j-1个字符匹配,且s1的第j个字符等于s3的第i+j个字符,那么s2的前i个字符和s1的前j个字符能否与s3的前i+j-1个字符匹配。

前两个for循环注意i可以等于s1.size(),因为二维数组每一维都多一个。下面的双重for循环也是注意条件里的等于情况,还有当确定一个i和j时,注意在映射到s1和s2的下标要减1.

class Solution {public:    bool isInterleave(string s1, string s2, string s3) {        if(s1.size() + s2.size() != s3.size())  return false;        vector<vector<int>> dp(s1.size()+1, vector<int>(s2.size()+1, 0));        dp[0][0] = 1;        for(int i = 1; i <= s1.size(); ++i){            dp[i][0] = (dp[i-1][0] == 1 && s1[i-1] == s3[i-1]);        }        for(int j = 1; j <= s2.size(); ++j){            dp[0][j] = (dp[0][j-1] == 1 && s2[j-1] == s3[j-1]);        }        for(int i = 1; i <= s1.size(); ++i){            for(int j = 1; j <= s2.size(); ++j){                if((dp[i-1][j] == 1 && s1[i-1] == s3[i-1+j]) || (dp[i][j-1] == 1 && s2[j-1] == s3[i+j-1]))                    dp[i][j] = 1;                else                    dp[i][j] = 0;            }        }        return dp[s1.size()][s2.size()];    }};




原创粉丝点击