给出三个字符串:s1、s2、s3,判断s3是否由s1和s2交叉构成。
样例
比如 s1 = "aabcc" s2 = "dbbca"
当 s3 = "aadbbcbcac",返回 true.
当 s3 = "aadbbbaccc", 返回 false.
很多人看到这个题的第一反应是用指针,依次遍历三个字符串,但是那样无法解决选择的问题,比如s1和s2都有相同的一个字母可以和s3匹配,但是由于顺序问题可能就会导致得出错误的结果。
这种类似的字符串问题可以使用动态规划的方法,建立一个二维数组dp,dp[i][j]表示s3可以由s1的前i个和s2的前j个组成,那么子问题就是dp[i-1][j]或者dp[i][j-1],只有子问题成立(true),该问题才会成立。而dp[i-1][j]的子问题是dp[i-2][j]或者dp[i-1][j-1],以此类推,最后都会归结为判断dp[1][0]或者dp[0][1]。
class Solution {
public:
/**
* Determine whether s3 is formed by interleaving of s1 and s2.
* @param s1, s2, s3: As description.
* @return: true of false.
*/
bool isInterleave(string s1, string s2, string s3) {
// write your code here
if(s3.size() != s1.size() + s2.size())
return false;
vector<vector<bool> > dp(s1.size() + 1,vector<bool>(s2.size() + 1,false));
dp[0][0] = true;
for(int i = 1;i <= s1.size();i++)
dp[i][0] = (dp[i - 1][0] && (s3[i - 1] == s1[i - 1]));
for(int i = 1;i <= s2.size();i++)
dp[0][i] = (dp[0][i - 1] && (s3[i - 1] == s2[i - 1]));
for(int i = 1;i <= s1.size();i++)
{
for(int j = 1;j <= s2.size();j++)
{
int t = i + j;
if(s1[i - 1] == s3[t - 1])
dp[i][j] = dp[i][j] || dp[i - 1][j];
if(s2[j - 1] == s3[t - 1])
dp[i][j] = dp[i][j]||dp[i][j - 1];
}
}
return dp[s1.size()][s2.size()];
}
};
网友评论