这道题比较简单,一开始写的递归,后来改成循环,发现都超时。
写了一个简易版本的dp,如下所示:
dp[i][j]定义:s1[1...i],s2[1...j]能否顺序匹配 s3[i+j]
状态转移方程:有两种状态:
1. dp[i][j] = dp[i-1][j], if dp[i-1][j] && s1[i] == s3[i+j]
** 表示s1的第i个字符匹配s3的第i+j个字符;**
2. dp[i][j] = dp[i][j-1], if dp[i][j-1] && s2[j] == s3[i+j]
** 表示s2的第j个字符匹配s3的第i+j个字符;**
上面两种情况,只要有一个结果为true,那么当前的匹配就为true

class Solution {
public:
    bool isInterleave(string s1, string s2, string s3) {
        int len1 = s1.size(),
            len2 = s2.size(),
            len3 = s3.size();

        if(len1+len2 != len3) return false;
        //把三个字符串均右移一个位置,从1开始索引,方便计算,哈哈!
        s1.insert(0, " ");
        s2.insert(0, " ");
        s3.insert(0, " ");
        // [1...len1][1...len2]为有效区间,
        vector<vector<bool> > dp(len1+1, vector<bool>(len2+1, false));
        // 首先分三步进行初始化
        dp[0][0] = true;
        for(int j = 1; j <= len2; j++) 
            if(s2[j] == s3[j]) dp[0][j] = dp[0][j-1];
        for(int i = 1; i <= len1; i++) 
            if(s1[i] == s3[i]) dp[i][0] = dp[i-1][0];

        for(int i = 1; i <= len1; i++) {
            for(int j = 1; j <= len2; j++) {
                // 大佬们的回复都是直接用一个开关,我改成这一种if判断的情况,方便大家理解
                // 请勿喷,我喜欢看起来简单的东西
                if((dp[i-1][j] && s1[i] == s3[i+j]) || 
                   (dp[i][j-1] && s2[j] == s3[i+j])) {
                    dp[i][j] = true;
                }
            }
        }
        return dp[len1][len2];
    }
};