29 Cross Strings

Original title URL: https://www.lintcode.com/zh-cn/problem/interleaving-string/#

Given three strings: s1, s2, s3, determine whether s3 is formed by the intersection of s1 and s2.

 

Sample

比如 s1 = "aabcc" s2 = "dbbca"

    - When s3 =  "aadbbcbcac" , return true.

    - When s3 =  "aadbbbaccc" , return false.

challenge 

Requires time complexity of O(n^2) or better

Label 
 
The idea: dynamic programming.
 
[As long as you encounter a subsequence of a string or a matching problem, go directly to Dynamic Programming.
 
dp[i][j] means whether the first i+j characters of s3 can be composed of the first i of s1 and the first j of s2, then the sub-problem is dp[i-1][j] or dp[i][ j-1], the problem will only hold if the subproblem holds (true) and the i+jth character of s3 is the same as the ith character of s1 or the same as the jth character of s2.
 
The essence is to find dp, the two-dimensional array of dp comes out, and you can directly return dp[s1.size()][s2.size()] .
 
dp[0][0]=true, because the first 0 characters of s3 must be composed of the first 0 characters of s1 and the first 0 characters of s2;
dp[i][j]: If dp[i-1][j] is true, it means that the first i-1+j characters of s3 are composed of the first i-1 characters of s1 and the first j characters of s2. If the i+j character s3[i+j-1] of s3 is equal to the i character s1[i-1] of s1, then dp[i][j] must be true.
             If dp[i][j-1] is true, the first i-1+j characters of s3 are composed of the first i characters of s1 and the first j-1 characters of s2. If the i+jth character of s3 is s3[i +j-1] is equal to the jth character s2[j-1] of s2, then dp[i][j] must be true.
即dp[i][j] = dp[i-1][j] && (s3[i+j-1] == s1[i-1]) || dp[i][j-1] && ( s3[i+j-1] == s2[j-1] ) .
 
Considering the boundary conditions to find dp[i][j], that is, the first row and first column of dp, i or j is equal to 0, i-1, j-1 is less than 0, the string subscript is out of bounds, so it needs to be processed separately . These two cases are equivalent to independently judging whether the top n bits of s3 are composed of the top n bits of s1 or the top n bits of s2. Two for loops are enough, which is essentially the same as finding dp[i][j], but no need Consider the case of the other half of the || operation, since the other half is equivalent to non-existence.
 
AC code:
class Solution {
public:
    /**
     * @param s1: A string
     * @param s2: A string
     * @param s3: A string
     * @return: Determine whether s3 is formed by interleaving of s1 and s2
     */
    bool isInterleave(string &s1, string &s2, string &s3) {
        // write your code here
        int size1=s1.size();
    int size3=s3.size();
    int size2=s2.size();
    if ((size1+size2)!=size3)
    {
        return false;
    }
    if (size1==0)
    {
        return s2==s3;
    }
    if (size2==0)
    {
        return s1==s3;
    }
    vector<vector<bool>> dp(size1+1,vector<bool>(size2+1,false));//动态规划数组;
    dp[0][0]=true;
    for (int i=1;i<=size1;i++)
    {
        dp[i][ 0 ]=dp[i- 1 ][ 0 ]&&(s1[i- 1 ]==s3[i- 1 ]); // the index of dp array is 1 larger than s1, s2, s3, So the current bits of s1, s2, s3 are i-1; 
    }
     for ( int j= 1 ;j<=size2;j++ )
    {
        dp[0][j]=dp[0][j-1]&&(s2[j-1]==s3[j-1]);
    }

    for (int i=1;i<=size1;i++)
    {
        for (int j=1;j<=size2;j++)
        {
            dp[i][j]=(dp[i-1][j]&&s3[i-1+j]==s1[i-1]||dp[i][j-1]&&s3[j-1+i]==s2[j-1]);
        }
    }
    return dp[size1][size2];
    }
};

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324978687&siteId=291194637
29