Skip to content

Commit 02b3fa9

Browse files
committed
97 Interleaving String
1 parent 4142c52 commit 02b3fa9

File tree

5 files changed

+205
-0
lines changed

5 files changed

+205
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
+ [65 Valid Number(细节题,状态机)](algorithms/ValidNumber)
2828
+ [72 Edit Distance(DP)](algorithms/EditDistance)
2929
+ [75 Sort Colors](algorithms/SortColors)
30+
+ [97 Interleaving String(DP)](algorithms/InterleavingString)
3031
+ [100 Same Tree](algorithms/SameTree)
3132
+ [101 Symmetric Tree](algorithms/SymmetricTree)
3233
+ [104 Maximum Depth of Binary Tree](algorithms/MaximumDepthofBinaryTree)
+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
## Interleaving String
2+
3+
Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.
4+
5+
For example,
6+
Given:
7+
```
8+
s1 = "aabcc",
9+
s2 = "dbbca",
10+
11+
When s3 = "aadbbcbcac", return true.
12+
When s3 = "aadbbbaccc", return false.
13+
```
14+
15+
## Solution
16+
17+
递归法
18+
19+
设三个字符指针分别为`s1,s2,s3`, 当前位置`i, j , k`, 判决函数`isInterleave(i, j, k)`:
20+
21+
* `s1,s2,s3`都为空,返回`true`
22+
* len表示字符串长度,若`len(s1) + len(s2) != len(s3)`,返回`false`
23+
*`s1[i] == s3[k],DFS搜寻,`isInterleave(i + 1, j, k + 1) == true`, 返回true, 否则下一步
24+
*`s2[j] == s3[k], DFS搜寻, `isInterleave(i, j + 1, k + 1) == true`, 返回true, 否则下一步
25+
* 返回false
26+
27+
## Code
28+
```cpp
29+
bool isInterleave(const char *s1, const char *s2, const char *s3) {
30+
if (*s1 == 0 && *s2 == 0 && *s3 == 0)
31+
return true;
32+
if (*s1 == *s3 && isInterleave(s1 + 1, s2, s3 + 1))
33+
return true;
34+
if (*s2 == *s3 && isInterleave(s1, s2 + 1, s3 + 1))
35+
return true;
36+
return false;
37+
}
38+
```
39+
40+
代码简单,思路简单,纯粹就是DFS。缺点是当有大量字符相等时,搜索路径很大,深度高,因此TLE
41+
42+
## Solution 2
43+
44+
DP法
45+
46+
设`dp[i][j]`,表示s1前i个字符,s2前j个字符匹配s3 前i + j个字符情况.
47+
48+
* 若`s3[i + j - 1] == s1[i - 1] && dp[i - 1][j] == true`, `dp[i][j] = true`,否则下一步:
49+
* 若`s3[i + j - 1] == s2[j - 1] && dp[i][j - 1] == true`, `dp[i][j] = true`,否则下一步
50+
* `dp[i][j] = false`
51+
52+
## Code
53+
```cpp
54+
bool dp_isInterleave(string s1, string s2, string s3) {
55+
int len1 = s1.size(), len2 = s2.size(), len3 = s3.size();
56+
if (len1 + len2 != len3)
57+
return false;
58+
vector<vector<int>> dp(len1 + 1, vector<int>(len2 + 1, false));
59+
dp[0][0] = true;// 空字符匹配空字符
60+
for (int i = 1; i <= len1; ++i) // 只匹配s1
61+
if (s1[i - 1] == s3[i - 1])
62+
dp[i][0] = true;
63+
else
64+
break;
65+
for (int j = 1; j <= len2; ++j) // 只匹配s2
66+
if (s2[j - 1] == s3[j - 1])
67+
dp[0][j] = true;
68+
else
69+
break;
70+
for (int i = 1; i <= len1; ++i)
71+
for (int j = 1; j <= len2; ++j) {
72+
if (s1[i - 1] == s3[i + j - 1])
73+
dp[i][j] |= dp[i-1][j];
74+
if (s2[j - 1] == s3[i + j - 1])
75+
dp[i][j] |= dp[i][j - 1];
76+
}
77+
return dp[len1][len2];
78+
}
79+
```
80+
81+
## cpp 重载问题
82+
83+
```cpp
84+
void foo(string s) {
85+
foo(s.c_str());
86+
}
87+
void foo(char *s) {
88+
cout << s << endl;
89+
}
90+
```
91+
以上代码会暴栈,原因在于`foo(string s)`不会调用`foo(char *s)`,而是调用其自身。。。。
92+
93+
一个原因是`s.c_str()`返回的是`const char *`和`char *`签名不一样,因此不调用。。。。。
94+
```cpp
95+
void foo(string s) {
96+
foo(s.c_str());
97+
}
98+
void foo(const char *s) {
99+
cout << s << endl;
100+
}
101+
```
102+
103+
以上代码仍然不能正常运行,原因是`foo(string s)`声明时`foo(const char *s)`并没有声明,找不到该函数,因此和自身匹配调用自身.
104+
105+
```cpp
106+
void foo(const char *s)
107+
{
108+
cout << s << endl;
109+
}
110+
void foo(string s)
111+
{
112+
foo(s.c_str());
113+
}
114+
```
115+
116+
以上代码运行正常。
117+
118+
**总结: c++ 是一门复杂危险的语言**

algorithms/InterleavingString/in.txt

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
aabcc dbbca aadbbcbcac
2+
aabcc dbbca aadbbbaccc
3+
a a aa
4+
a b ab
5+
a b ba
6+
abc def abcdef
7+
abc def defabc
+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#include <string>
2+
#include <vector>
3+
#include <iostream>
4+
#include <cstdlib>
5+
using namespace std;
6+
class Solution {
7+
public:
8+
bool isInterleave(string s1, string s2, string s3) {
9+
return recursive_isInterleave(s1, s2, s3);
10+
}
11+
private:
12+
bool dp_isInterleave(string s1, string s2, string s3) {
13+
int len1 = s1.size(), len2 = s2.size(), len3 = s3.size();
14+
if (len1 + len2 != len3)
15+
return false;
16+
vector<vector<int>> dp(len1 + 1, vector<int>(len2 + 1, false));
17+
dp[0][0] = true;
18+
for (int i = 1; i <= len1; ++i)
19+
if (s1[i - 1] == s3[i - 1])
20+
dp[i][0] = true;
21+
else
22+
break;
23+
for (int j = 1; j <= len2; ++j)
24+
if (s2[j - 1] == s3[j - 1])
25+
dp[0][j] = true;
26+
else
27+
break;
28+
for (int i = 1; i <= len1; ++i)
29+
for (int j = 1; j <= len2; ++j) {
30+
if (s1[i - 1] == s3[i + j - 1])
31+
dp[i][j] |= dp[i-1][j];
32+
if (s2[j - 1] == s3[i + j - 1])
33+
dp[i][j] |= dp[i][j - 1];
34+
}
35+
return dp[len1][len2];
36+
}
37+
bool recursive_isInterleave(string s1, string s2, string s3) {
38+
const char *p1 = s1.c_str(), *p2 = s2.c_str(), *p3 = s3.c_str();
39+
return recursive_isInterleave(p1, p2, p3);
40+
}
41+
bool recursive_isInterleave(const char *s1, const char *s2, const char *s3) {
42+
if (*s1 == 0 && *s2 == 0 && *s3 == 0)
43+
return true;
44+
if (*s1 == *s3 && recursive_isInterleave(s1 + 1, s2, s3 + 1))
45+
return true;
46+
if (*s2 == *s3 && recursive_isInterleave(s1, s2 + 1, s3 + 1))
47+
return true;
48+
return false;
49+
}
50+
};
51+
int main(int argc, char **argv)
52+
{
53+
Solution solution;
54+
char s1[20], s2[20], s3[40];
55+
cout << solution.isInterleave(string(), "b", "b") << endl;
56+
while (scanf("%s%s%s", s1, s2, s3) != EOF) {
57+
cout << solution.isInterleave(string(s1), string(s2), string(s3)) << endl;
58+
}
59+
return 0;
60+
}
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include <string>
2+
#include <iostream>
3+
using namespace std;
4+
//void foo(char *s) {
5+
// cout << s << endl;
6+
//}
7+
void foo(const char *s)
8+
{
9+
cout << s << endl;
10+
}
11+
void foo(string s) {
12+
foo(s.c_str());
13+
}
14+
int main(int argc, char **argv)
15+
{
16+
string s = "hello";
17+
foo(s);
18+
return 0;
19+
}

0 commit comments

Comments
 (0)