题目链接:Interleaving String

Given s1, s2, s3, 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.

这道题的要求是检测字符串s3是否由s1和s2交错生成。

这是一道动态规划的题目,用dp[i, j]表示s1的前i个字符和s2的前j个字符能否通过交错生成s3的前i+j个字符。

至于dp数组的初值,当j等于0的时候,dp[i, 0]的值取决于dp[i-1, 0]是否为真以及s1[i-1]是否等于s3[i-1],即

  • dp[i][0] = dp[i-1][0] && s1[i-1] == s3[i-1]

同理,当i等于0的时候:

  • dp[0][j] = dp[0][j-1] && s2[j-1] == s3[j-1]

至于递推公式,取决于当期读到的字符是否等于s3中对应的字符相同:

  • 如果s1[i-1]与s3[i+j-1]相同,说明当前位置s1可以进行匹配,因此如果dp[i-1, j]也为真,dp[i, j]就为真。
  • 如果s2[j-1]与s3[i+j-1]相同,说明当前位置s2可以进行匹配,因此如果dp[i, j-1]也为真,dp[i, j]就为真。

综上所述,递推公式为dp[i, j] = (s1[i-1] == s3[i+j-1] && dp[i-1, j]) || (s2[j-1] == s3[i+j-1] && dp[i, j-1])。

注意一下,如果s1的长度加上s2的长度不等于s3的长度,则直接返回false即可。

时间复杂度:O(nm)

空间复杂度:O(nm)

 1 class Solution
 2 {
 3 public:
 4     bool isInterleave(string s1, string s2, string s3)
 5     {
 6         int l1 = s1.size(), l2 = s2.size(), l3 = s3.size();
 7 
 8         if(l3 != l1 + l2)
 9             return false;
10 
11         vector<vector<bool> > dp(l1 + 1, vector<bool>(l2 + 1, false));
12 
13         dp[0][0] = true;
14         for(int i = 1; i <= l1; ++ i)
15             dp[i][0] = dp[i - 1][0] && s1[i - 1] == s3[i - 1];
16         for(int j = 1; j <= l2; ++ j)
17             dp[0][j] = dp[0][j - 1] && s2[j - 1] == s3[j - 1];
18 
19         for(int i = 1; i <= l1; ++ i)
20             for(int j = 1; j <= l2; ++ j)
21                 dp[i][j] = (s1[i - 1] == s3[i + j - 1] && dp[i - 1][j]) 
22                         || (s2[j - 1] == s3[i + j - 1] && dp[i][j - 1]);
23 
24         return dp[l1][l2];
25     }
26 };

这道题还有人给出了BFS的方法。