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.
dp[i j] 表示s1[0 - i]是否与s2[0 - j]是交叉串。
- 则空串与空串为true,即dp[0][0] = 1;
- dp[i][j] = (dp[i][j - 1] && s2[j - 1] == s3[i + j - 1]) || (dp[i - 1][j] && s1[i - 1] == s3[i + j - 1]);
dp[i][j]为真时,肯定是s1[0,i]与s2[0-j]交叉组成 串s3 的 [0 ,i + j -1],s3[i + j - 1] = s1[i] OR s2[j],
则 当s3[i + j - 1] == s1[i] && dp[i][j - 1] && s2[j - 1] 或者dp[i - 1][j] && s1[i - 1] == s3[i + j - 1]);时为真
- 这里要注意当i 或者j 为0时 i-1 (j - 1)越界的问题!
- 对于两个数组i,j关系的问题,考虑局部0-i 和0-j,最后以dp公式,得出0-i 与0-j的关系即可!
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
int len1 = s1.size();
int len2 = s2.size();
int len3 = s3.size();
//长度不相等,false
if(len1 + len2 != len3)return false;
vector<vector<int> >dp;
vector<int>v;
for(int i = 0; i <= len1; i++)
{
v.clear();
for(int j = 0; j <= len2; j++)
v.push_back(0);
dp.push_back(v);
}
//在对字符串,数组固定取值时,先判断下标是否越界
if(len1 && s1[0] == s3[0])dp[1][0] = 1;
if(len2 && s2[0] == s3[0])dp[0][1] = 1;
dp[0][0] = 1;
for(int i = 0; i <= len1; i++)
{
for(int j = 0; j <= len2; j++)
{
//对于可能越界的直接用if 省事
if(!i && j)//i = 0时只需考虑dp[i][j - 1] 、s2[j - 1]
dp[i][j] = dp[i][j - 1] && s2[j - 1] == s3[i + j - 1];
else if(i && !j)//i = 0时只需考虑dp[i - 1][j] 、s2[i - 1],即dp[0][i]是否是交叉串
dp[i][j] = dp[i - 1][j] && s1[i - 1] == s3[i + j - 1];
else if(i && j)
dp[i][j] = (dp[i][j - 1] && s2[j - 1] == s3[i + j - 1]) || (dp[i - 1][j] && s1[i - 1] == s3[i + j - 1]);
}
}
return dp[len1][len2];
}
};