97. 交错字符串
题目描述
给定三个字符串 s1
, s2
, s3
, 验证 s3
是否是由 s1
和 s2
交错组成的。
示例 1:
输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
输出: true
示例 2:
输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
输出: false
思路
设dp[i][j]
表示s3
的前i+j
个字符可以由s1
的前i
个字符和s2
的前j
个字符交织而成。这种字符串类型的动态规划和以前遇到的动态规划类似,只不过每一个位置的处理情况(s3
每一个位置的处理情况分为两种:用s1
,或者用s2
)有好几种,其实这个问题我们还可以从第一个位置开始处理后决定后面的子问题,这样似乎显得的更自然一些,第一个位置可以用s1
的第一个字符,如果s1[1] == s3[1]
,然后判断子问题s1[2:size1]
,s2[1:size2]
,s3[2:size3]
,如果s2[1] == s3[1]
,然后判断子问题s1[1:size1]
,s2[2:size2]
,s3[2:size3]
,不过这样解决问题,书写上不如从最后处理流畅.
代码实现
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
int size1 = s1.size();
int size2 = s2.size();
int size3 = s3.size();
if(size1+size2 != size3)
return false;
//为了递推公式的方便,我们需要人为的创造长度为0时的情况,
//所以这里的dp用的是长度而不是下标
vector<vector<bool> > dp(size1+1, vector<bool>(size2+1, false));
for(int i = 0; i <= size1; i ++)
{
for(int j = 0; j <= size2; j ++)
{
if(i == 0 && j == 0)
// start
dp[i][j] = true;
else if(i == 0)
dp[0][j] = dp[0][j-1] && (s2[j-1]==s3[j-1]);
else if(j == 0)
dp[i][0] = dp[i-1][0] && (s1[i-1]==s3[i-1]);
else
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[size1][size2];
}
};