【ATT】Interleaving String

Q:

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.

A: DP题。这道题hulu面试出过,当时sb了,想着用递归做,但是考虑一种极限情况 XXX ,XXX,XXXXXX. 如果递归的话,分支每次要走两个支路,复杂度是O(2^n).

实际上应该用DP做。二维DP。用dp[i][j]表示s3[1~i+j]是否由s1[1~i]和s2[1~j]交织而成的。

如果s1[i] == s3[i+j]&&s2[j]!=s3[i+j],那么dp[i][j] = dp[i-1][j];

如果s1[i] != s3[i+j]&&s2[j]==s3[i+j],那么dp[i][j] = dp[i][j-1];

如果s1[i] == s3[i+j]&&s2[j]==s3[i+j],那么dp[i][j] = dp[i-1][j]||dp[i][j-1];

否则,dp[i][j] = false;

注意,边界条件的处理,当i=0||j==0的时候。

    bool isInterleave(string s1, string s2, string s3) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int m = s1.size();
        int n = s2.size();
        int l = s3.size();
        
        if(m+n!=l)
            return false;
            
        vector<vector<bool>> dp(m+1,vector<bool>(n+1,false));
        int i,j;
        dp[0][0] = true;
        for(j=1;j<=n;j++)
        {
            if(s3[j-1] == s2[j-1])
                dp[0][j] = dp[0][j-1];
        }
        
        for(i=1;i<=m;i++)
        {
            if(s1[i-1] == s3[i-1])
                dp[i][0] =dp[i-1][0];
        }
        
        for(i=1;i<=m;i++)
        {
            for(j=1;j<=n;j++)
            {
                if(s1[i-1]==s3[i+j-1]&&s2[j-1]!=s3[i+j-1])
                    dp[i][j] = dp[i-1][j];
                else if(s2[j-1]==s3[i+j-1]&&s1[i-1]!=s3[i+j-1])
                    dp[i][j] = dp[i][j-1];
                else if(s1[i-1]==s3[i+j-1]&&s2[j-1]==s3[i+j-1])
                    dp[i][j] = dp[i-1][j]||dp[i][j-1];
            }
        }
        
        return dp[m][n];
        
        
    }

  

posted @ 2013-09-24 15:55  summer_zhou  阅读(123)  评论(0编辑  收藏  举报