LeetCode | Interleaving String(交叉字符串)


Given s1s2s3, 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.

题目解析:

看s1和s2正序交替排列是否能得到目标串。


方案一:递归方法

由于两个子串是从前向后与目标串匹配的,那么可以一个一个去比较,当s1[index1] == s2[index2]的时候,就进行递归:先按照s1当前值与目标串s3相等,递归;如果不能匹配,则按照s2与s3当前值相等,递归;最后再进行一次判断。

由于递归耗时,造成时间超限……

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

        if(len1+len2 != len3)
            return false;
        return Judge(s1,0,s2,0,s3,0);
    }
    bool Judge(string s1,int index1,string s2,int index2,string s3,int index3){
        if(index3 == s3.size())
            return true;
        if(index1 == s1.size()){
            while(index2 < s2.size()){
                if(s2[index2] != s3[index3])
                    return false;
                index2++;
                index3++;
            }
            return true;
        }
        if(index2 == s2.size()){
            while(index1 < s1.size()){
                if(s1[index1] != s3[index3])
                    return false;
                index1++;
                index3++;
            }
            return true;
        }
        bool flag1 = false,flag2 = false;
        if(s1[index1] == s3[index3])    //如果两个相等,就递归进去
            flag1 = Judge(s1,index1+1,s2,index2,s3,index3+1);

        if(flag1 == false){ //如果递归失败,或者s1[index1] != s3[index3]
            if(s2[index2] == s3[index3])
                flag2 = Judge(s1,index1,s2,index2+1,s3,index3+1);
            else
                return false;
        }

        return flag1 || flag2;
    }
};

方案二:

时间超限问题,我们可以利用动态规划来解决。假设0…len1和0….len2已经于0…len3进行匹配了,然后增加一个值len3+1,那么要么满足0…len1+1且0….len2  要么满足0…len1和0….len2+1。基于这个思想,就定义一个二维数组。填写动态规划产生的中间值,以空间换取时间上的节省。——–因此,空间换时间不光用在提高时间复杂度上面,也用在动态规划中!要有这个思想。

class Solution {
private:
    bool f[1000][1000];
public:
    bool isInterleave(string s1, string s2, string s3) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function 
        if (s1.size() + s2.size() != s3.size())
            return false;
            
        f[0][0] = true;
        for(int i = 1; i <= s1.size(); i++)
            f[i][0] = f[i-1][0] && (s3[i-1] == s1[i-1]);
            
        for(int j = 1; j <= s2.size(); j++)
            f[0][j] = f[0][j-1] && (s3[j-1] == s2[j-1]);
            
        for(int i = 1; i <= s1.size(); i++)
            for(int j = 1; j <= s2.size(); j++)
                f[i][j] = (f[i][j-1] && s2[j-1] == s3[i+j-1]) || (f[i-1][j] && s1[i-1] == s3[i+j-1]);
                
        return f[s1.size()][s2.size()];
    }
};



点赞