LC

题目

思路

这个题的题面比较具有误导性,主要是“交错”一词让人摸不着头脑,感觉需要去枚举所有s1 和 s2 的子串。但其实换一个角度看会豁然开朗,假设s3是合法的交错字符串,那么s3上的每一个字符都来自s1或者s2,并且是保序的。想到这,问题就变成了一个简单的二维DP问题了。

f[i,j]表示由s1[1~i]s2[1~j]交错构成s3[1~i+j]的所有方案的集合,它的值是bool变量,表示集合是否为空。(也就是是否能交错构成)

显然, f[i,j] = f[i-1,j] || f[i,j-1],当s1[i] == s3[i+j]时存在左边情况,当s2[j] == s3[i+j]存在右边情况。

时间复杂度:状态有$O(n^2)$个,状态转移只需要$O(1)$,因此总的时间复杂度为$O(n^2)$

代码

class Solution {
public:
    bool isInterleave(string s1, string s2, string s3) {
        int n = s1.size(), m = s2.size();
        if(n + m != s3.size()) return false;

        s1 = ' ' + s1, s2 = ' ' + s2, s3 = ' ' + s3;

        vector<vector<bool>> f(n + 1, vector<bool>(m + 1));

        
        for(int i = 0; i <= n; i++){
            for(int j = 0; j <= m; j++) {
                if(!i && !j) f[i][j] = true;
                else {
                    if(i && s1[i] == s3[i + j]) f[i][j] = f[i - 1][j];
                    if(j && s2[j] == s3[i + j]) f[i][j] = f[i][j] || f[i][j - 1];
                }
            }
        }
        
        return f[n][m];
    }
};