1.题目描述
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.
来自 <https://leetcode.com/problems/interleaving-string/>
2.要点
二维动态规划
3.分析
错误的思路:
一开始以为在S3中遍历属于S1的字符,然后删除,剩下的字符如果和S2比较是否相等。
但是当S1和S2如果同时匹配时会出现错误。如S1 = "aa", S2 = "ab", S3 ="abaa",正确结果应该返回true,但是是按照这个思路会返回false。
正确的解法:
还是要灵活运用动态规划来解题。
用dp[m][n]表示S1的前m个字符和S2的前n个字符能够交叉形成S3的前m+n个字符。
观察可以得到如下规律:
dp[i][j] = (dp[i-1][j] && (s3[i-1+j] == s1[i-1])) || (dp[i][j-1] && (s3[i+j-1] == s2[j-1]));
需要注意的是:这里dp[i][j]中,i表示的S1的第一个到第i个字符串,并不是下标。
source code:
</pre><pre name="code" class="cpp">class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
int m = s1.size();
int n = s2.size();
if(m+n != s3.size()) return false;
vector<vector<bool>> dp( m+1, vector<bool> (n+1));
dp[0][0] = true;
for(int i=1;i<=m;i++)
dp[i][0] = dp[i-1][0] && (s3[i-1] == s1[i-1]);
for(int j=1;j<=n;j++)
dp[0][j] = dp[0][j-1] && (s3[j-1] == s2[j-1]);
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
dp[i][j] = (dp[i-1][j] && (s3[i-1+j] == s1[i-1])) ||
(dp[i][j-1] && (s3[i+j-1] == s2[j-1]));
}
}
return dp[m][n];
}
};