题目:

Given s1s2s3, find whether s3 is formed by the interleaving of s1 and s2.

For example,
Given:
s1 = "aabcc",
s2 = "dbbca",

When s3 = "aadbbcbcac", return true.
When s3 = "aadbbbaccc", return false.

代码:

“merge sort + stack”

        struct LastMatch{
int i1;
int i2;
int i3;
LastMatch(int i1, int i2, int i3): i1(i1), i2(i2), i3(i3){}
};
static bool isInterleave(string s1, string s2, string s3)
{
const int n1 = s1.size();
const int n2 = s2.size();
const int n3 = s3.size();
if ( n1+n2 != n3 ) return false;
stack<LastMatch> sta;
int i1=,i2=,i3=;
while ( i1<n1 || i2<n2 || i3<n3 )
{
if ( s1[i1]==s2[i2] && s2[i2]==s3[i3] ){
sta.push(LastMatch(i1,i2,i3));
i1++; i3++;
}
else if ( s1[i1]==s3[i3] ){
i1++; i3++;
}
else if ( s2[i2]==s3[i3] ){
i2++; i3++;
}
else if ( !sta.empty() ){
LastMatch lm = sta.top(); sta.pop();
i1 = lm.i1; i2 = lm.i2; i3 = lm.i3;
i2++; i3++;
}
else{
return false;
}
}
return i1==n1 && i2==n2 && i3==n3;
}

"dp"

class Solution {
public:
bool isInterleave(string s1, string s2, string s3)
{
const int n1 = s1.size();
const int n2 = s2.size();
const int n3 = s3.size();
if ( n1+n2 != n3 ) return false;
vector<vector<bool> > dp(n1+, vector<bool>(n2+, false));
dp[][] = true;
// check s1 boundary
for ( int i = ; i <= n1; ++i ){
dp[i][] = s1[i-]==s3[i-] && dp[i-][];
}
// check s2 boundary
for ( int i = ; i <= n2; ++i ){
dp[][i] = s2[i-]==s3[i-] && dp[][i-];
}
// dp process
for ( int i = ; i<=n1; ++i )
{
for ( int j = ; j<=n2; ++j )
{
dp[i][j] = ( s1[i-]==s3[i+j-] && dp[i-][j] )
|| ( s2[j-]==s3[i+j-] && dp[i][j-] );
}
}
return dp[n1][n2];
}
};

tips:

这道题第一版采用“merge sort + stack”,有一个大集合过不去,报超时(但即使跟可以AC的dp方法对比,“merge sort+stack”过这个大集合也仅仅慢了不到10%,在数量级上应该没有差别,时间复杂度都是O(n²))

dp的解法是学习网上的解法,理解如下:

dp[i][j]表示s1[0~i-1]与s2[0~j-1]是否匹配s3[0~i+j-1]

因此为了方便,定义dp[n+1][m+1],多一个维度,目的是保证从s1中取的个数从0到n都可以表示(s2同理)。

可以写出来dp的通项公式:

dp[i][j] = ( s1[i-1]==s3[i+j-1] && dp[i-1][j] ) || ( s2[j-1]==s3[i+j-1] && dp[i][j-1] )

表示s3第i+j个元素要么由s1匹配上,要么由s2匹配上。

最后返回dp[n1][n2]就是所需的结果。

整个dp的过程并不复杂,思考下如何得来的:

1. dp取两个维度是因为s1和s2两个变量

2. 之前自己思考dp的时候,考虑的是每个位置可以由s1或者s2其中的元素表示,但是这样考虑起来就太复杂了;网上的思路并么有考虑到这么复杂,而是仅仅考虑s3中总共就这么长字符串,某个长度的字符串可以从s1和s2各取几个。

============================================

上述的dp过程的空间复杂度是O(n²)的,再采用滚动数组方式,把空间复杂度降低到O(n),代码如下:

class Solution {
public:
bool isInterleave(string s1, string s2, string s3)
{
const int n1 = s1.size();
const int n2 = s2.size();
const int n3 = s3.size();
if ( n1+n2 != n3 ) return false;
vector<bool> dp(n2+, false);
// check s2 boundary
dp[] = true;
for ( int i = ; i<=n2; ++i )
{
dp[i] = s2[i-]==s3[i-] && dp[i-];
}
// dp process
for ( int i = ; i<=n1; ++i )
{
dp[] = s1[i-]==s3[i-] && dp[];
for ( int j = ; j<=n2; ++j )
{
dp[j] = ( s1[i-]==s3[i+j-] && dp[j] ) || ( s2[j-]==s3[i+j-] && dp[j-] );
}
}
return dp[n2];
}
};

tips:如果二维的dp过程只跟紧上一次的dp过程有关,就可以退化为滚动数组形式的一维dp过程。

=======================================

第二次过这道题,参照dp的思路写了一遍。有个细节就是dp递推公式的时候“s3[i+j-1]”不要写成s3[i-1]或者s3[j-1]。

class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
if ( (s1.size()+s2.size())!=s3.size() ) return false;
bool dp[s1.size()+][s2.size()+];
fill_n(&dp[][], (s1.size()+)*(s2.size()+), false);
dp[][] = true;
for ( int i=; i<=s1.size(); ++i )
{
dp[i][] = dp[i-][] && s1[i-]==s3[i-];
}
for ( int i=; i<=s2.size(); ++i )
{
dp[][i] = dp[][i-] && s2[i-]==s3[i-];
}
for ( int i=; i<=s1.size(); ++i )
{
for ( int j=; j<=s2.size(); ++j )
{
dp[i][j] = ( dp[i-][j] && s1[i-]==s3[i+j-] ) ||
( dp[i][j-] && s2[j-]==s3[i+j-] );
}
}
return dp[s1.size()][s2.size()];
}
};

【Interleaving String】cpp的更多相关文章

  1. 【Scramble String】cpp

    题目: Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty subs ...

  2. 【Valid Sudoku】cpp

    题目: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could ...

  3. 【WildCard Matching】cpp

    题目: Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any single charact ...

  4. 【Add binary】cpp

    题目: Given two binary strings, return their sum (also a binary string). For example,a = "11" ...

  5. 【Implement strStr() 】cpp

    题目: Implement strStr(). Returns the index of the first occurrence of needle in haystack, or -1 if ne ...

  6. 【Valid Palindrome】cpp

    题目: Given a string, determine if it is a palindrome, considering only alphanumeric characters and ig ...

  7. 【Valid Parentheses】cpp

    题目: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the ...

  8. 【Simplify Path】cpp

    题目: Given an absolute path for a file (Unix-style), simplify it. For example,path = "/home/&quo ...

  9. 【Valid Number】cpp

    题目: Validate if a given string is numeric. Some examples:"0" => true" 0.1 " = ...

随机推荐

  1. 零基础逆向工程27_Win32_01_宽字符_MessageBox_win32调试输出

    1 多字节字符 ASCII码表:0 ~ 2^7-1 扩展ASCII码表:2^7 ~ 2^8-1 什么是GB2312:1980年,两个字节存储一个汉字:不通用,别国会有乱码. UCICODE:只有一个字 ...

  2. 使用CMake生成VS2010项目查看OpenCV源代码

    近期项目需要用到OpenCV中的几个函数,但其函数无法全部实现自己需要的功能,故而需要改进部分函数,为安全及效率起见,想参考OpenCV的源码来改进,这样节省时间的同时亦可提供代码的鲁棒性和通用性.那 ...

  3. 用JavaScript访问SAP云平台上的服务遇到跨域问题该怎么办

    关于JavaScript的跨域问题(Cross Domain)的讨论, 网上有太多的资源了.国内的程序猿写了非常多的优秀文章,Jerry这里就不再重复了. 直入主题,最近我正在做一个原型开发:通过SA ...

  4. ELF文件的格式和加载过程

    http://blog.csdn.net/lingfong_cool/article/details/7832896 (一) ELF 文件的格式       ELF 文件类型 (1) 可重定位文件(  ...

  5. python_55_局部和全局变量

    school='Hebut'#school为全局变量 sex='male'#全局变量 names=['Wang Yu','Bai Jingyi','Zhang Yu'] hobby='姑娘' def ...

  6. 由一道CTF pwn题深入理解libc2.26中的tcache机制

    本文首发安全客:https://www.anquanke.com/post/id/104760 在刚结束的HITB-XCTF有一道pwn题gundam使用了2.26版本的libc.因为2.26版本中加 ...

  7. JoinQuant策略代码示例

    总体回测前 ''' ================================================================================ 总体回测前 === ...

  8. 分享12款最佳的Bootstrap设计工具

    设计师总会渴望有一些新奇有趣的设计工具来提高工作效率,而Bootstrap就是您的不二选择.2013年Bootstrap得到了广泛普及, 它是开发者较为常用的框架之一,本文我们将分享12款最佳的Boo ...

  9. 前端-带header和footer的双栏布局

    目标是实现如上图带header和footer的双栏布局,其中右侧sidebar是固定宽度,左侧content是自适应: https://www.zybuluo.com/dengzhirong/note ...

  10. ES6学习(一):数值的扩展

    chapter06 数值的扩展 6.1 二进制和八进制 二进制 前缀 0b 或者 0B 八进制 前缀 0o 或者 0O 6.2 Number.isFinite() Number.isNaN() 原先这 ...