Original title URL: https://www.lintcode.com/zh-cn/problem/interleaving-string/#
Given three strings: s1, s2, s3, determine whether s3 is formed by the intersection of s1 and s2.
Have you encountered this question in a real interview?
Yes
Sample
比如 s1 = "aabcc" s2 = "dbbca"
- When s3 = "aadbbcbcac" , return true.
- When s3 = "aadbbbaccc" , return false.
challenge
Requires time complexity of O(n^2) or better
Label
The idea: dynamic programming.
[As long as you encounter a subsequence of a string or a matching problem, go directly to Dynamic Programming. 】
dp[i][j] means whether the first i+j characters of s3 can be composed of the first i of s1 and the first j of s2, then the sub-problem is dp[i-1][j] or dp[i][ j-1], the problem will only hold if the subproblem holds (true) and the i+jth character of s3 is the same as the ith character of s1 or the same as the jth character of s2.
The essence is to find dp, the two-dimensional array of dp comes out, and you can directly return dp[s1.size()][s2.size()] .
dp[0][0]=true, because the first 0 characters of s3 must be composed of the first 0 characters of s1 and the first 0 characters of s2;
dp[i][j]: If dp[i-1][j] is true, it means that the first i-1+j characters of s3 are composed of the first i-1 characters of s1 and the first j characters of s2. If the i+j character s3[i+j-1] of s3 is equal to the i character s1[i-1] of s1, then dp[i][j] must be true.
If dp[i][j-1] is true, the first i-1+j characters of s3 are composed of the first i characters of s1 and the first j-1 characters of s2. If the i+jth character of s3 is s3[i +j-1] is equal to the jth character s2[j-1] of s2, then dp[i][j] must be true.
即dp[i][j] = dp[i-1][j] && (s3[i+j-1] == s1[i-1]) || dp[i][j-1] && ( s3[i+j-1] == s2[j-1] ) .
Considering the boundary conditions to find dp[i][j], that is, the first row and first column of dp, i or j is equal to 0, i-1, j-1 is less than 0, the string subscript is out of bounds, so it needs to be processed separately . These two cases are equivalent to independently judging whether the top n bits of s3 are composed of the top n bits of s1 or the top n bits of s2. Two for loops are enough, which is essentially the same as finding dp[i][j], but no need Consider the case of the other half of the || operation, since the other half is equivalent to non-existence.
AC code:
class Solution {
public:
/**
* @param s1: A string
* @param s2: A string
* @param s3: A string
* @return: Determine whether s3 is formed by interleaving of s1 and s2
*/
bool isInterleave(string &s1, string &s2, string &s3) {
// write your code here
int size1=s1.size();
int size3=s3.size();
int size2=s2.size();
if ((size1+size2)!=size3)
{
return false;
}
if (size1==0)
{
return s2==s3;
}
if (size2==0)
{
return s1==s3;
}
vector<vector<bool>> dp(size1+1,vector<bool>(size2+1,false));//动态规划数组;
dp[0][0]=true;
for (int i=1;i<=size1;i++)
{
dp[i][ 0 ]=dp[i- 1 ][ 0 ]&&(s1[i- 1 ]==s3[i- 1 ]); // the index of dp array is 1 larger than s1, s2, s3, So the current bits of s1, s2, s3 are i-1;
}
for ( int j= 1 ;j<=size2;j++ )
{
dp[0][j]=dp[0][j-1]&&(s2[j-1]==s3[j-1]);
}
for (int i=1;i<=size1;i++)
{
for (int j=1;j<=size2;j++)
{
dp[i][j]=(dp[i-1][j]&&s3[i-1+j]==s1[i-1]||dp[i][j-1]&&s3[j-1+i]==s2[j-1]);
}
}
return dp[size1][size2];
}
};