题目描述:
给定三个字符串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是判断一个串,这个题目是同时判断两个串。
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-06 14:21:07