题目描述:
给定三个字符串A, B, C,判断C是否由A和B交错构成。交错构成的意思是,对于字符串C,可以将其每个字符标记为A类或B类,使得我A类的每个字符顺序构成了A字符串,B类的每个字符顺序构成了B字符串。如:对于A=”rabbit” B=”mq”, ”rabmbitq”是由A和B交错构成的,但”rabbqbitm”不是由A和B交错构成。
解题思路:
1、直接顺序比较,从C中依次拿掉A,看剩下的是不是等于B,若是则返回true,否则,返回false. 但是如果A和B中有相同的字符,则这种方法会出错。
例如,A=“aa”, B=“ab”,C=“aaba” 这种情况下,上述这种方法会返回false,但实际上它是true。 因此这种方法不可行。
2、采用动态规划的方法
定义状态:dp[i][j] 代表是A的前i个字符与C中匹配,B中前j个字符与C中匹配.
递推的比较过程中如果知道s1,s2上的指针p,q的情况,s3上这个指针肯定在p+q的位置。利用这个结论,就可以设计出O(m1*m2)的DP方案。
执行操作分为两步,分别判断:
A[i-1] == C[i+j-1] 为真,则 dp[i][j] = dp[i][j] || dp[i-1][j]
B[j-1] == C[i+j-1] 为真,则dp[i][j] = dp[i][j] || dp[i][j-1]
最后返回:dp[i][j],此时,i=s1.lenth(), j=s2.length()
参考代码:
#include"iostream"
#include"vector"
using namespace std;
class Solution
{
public:
bool isInterleave(string s1, string s2, string s3)
{
size_t len1, len2;
len1 = s1.length();
len2 = s2.length();
if (len1 + len2 != s3.length())
return false;
vector<vector<bool>> dp;//定义变量
dp.resize(len1 + 1, vector<bool>(len2 + 1, false));//分配空间
dp[0][0] = true;
for (int i = 0; i <= len1 ;i++)
for (int j = 0; j <= len2 ; j++)
{
if (i == 0 && j == 0)
continue;
if (i>0){
if (s1[i - 1] == s3[i + j - 1]){
dp[i][j] = dp[i][j] || dp[i - 1][j];
}
}
if (j>0){
if (s2[j - 1] == s3[i + j - 1]){
dp[i][j] = dp[i][j] || dp[i][j - 1];
}
}
}
bool result = dp[len1][len2];
return result;
}
};
int main()
{
Solution S;
string s1 = "aa";
string s2 = "ab";
string s3 = "aaba";
bool ans = S.isInter(s1, s2, s3);
if (ans)
cout << "true" << endl;
else
cout << "false" << endl;
}
这道题目跟最长公共子序列有点相似,思路类似,稍作变换.
LCS是判断一个串,这个题目是同时判断两个串。
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/tommyzht/article/details/46813195