-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
130 lines (113 loc) · 3.75 KB
/
main.cpp
File metadata and controls
130 lines (113 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Source: https://leetcode.com/problems/interleaving-string
// Title: Interleaving String
// Difficulty: Medium
// Author: Mu Yang <http://muyang.pro>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Given strings `s1`, `s2`, and `s3`, find whether `s3` is formed by an **interleaving** of `s1` and `s2`.
//
// An **interleaving** of two strings `s` and `t` is a configuration where `s` and `t` are divided into `n` and `m` <button>substrings</button> respectively, such that:
//
// - `s = s_1 + s_2 + ... + s_n`
// - `t = t_1 + t_2 + ... + t_m`
// - `|n - m| <= 1`
// - The **interleaving** is `s_1 + t_1 + s_2 + t_2 + s_3 + t_3 + ...` or `t_1 + s_1 + t_2 + s_2 + t_3 + s_3 + ...`
//
// **Note:** `a + b` is the concatenation of strings `a` and `b`.
//
// **Example 1:**
// https://assets.leetcode.com/uploads/2020/09/02/interleave.jpg
//
// ```
// Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
// Output: true
// Explanation: One way to obtain s3 is:
// Split s1 into s1 = "aa" + "bc" + "c", and s2 into s2 = "dbbc" + "a".
// Interleaving the two splits, we get "aa" + "dbbc" + "bc" + "a" + "c" = "aadbbcbcac".
// Since s3 can be obtained by interleaving s1 and s2, we return true.
// ```
//
// **Example 2:**
//
// ```
// Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
// Output: false
// Explanation: Notice how it is impossible to interleave s2 with any other string to obtain s3.
// ```
//
// **Example 3:**
//
// ```
// Input: s1 = "", s2 = "", s3 = ""
// Output: true
// ```
//
// **Constraints:**
//
// - `0 <= s1.length, s2.length <= 100`
// - `0 <= s3.length <= 200`
// - `s1`, `s2`, and `s3` consist of lowercase English letters.
// **Follow up:** Could you solve it using only `O(s2.length)` additional memory space?
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <cstdint>
#include <string>
#include <vector>
using namespace std;
// 2D-DP
//
// Let DP[i][j] = true if s3[:(i+j)] can be form by s1[:i] and s2[:j].
//
// DP[0][0] = true
// DP[i][j] = (DP[i-1][j] AND s3[i+j-1] == s1[i-1])
// OR (DP[i][j-1] AND s3[i+j-1] == s2[j-1])
class Solution {
using Bool = uint8_t;
public:
bool isInterleave(const string &s1, const string &s2, const string &s3) {
const int m = s1.size(), n = s2.size();
// Guard
if (s3.size() != m + n) return false;
// DP
auto dp = vector<vector<Bool>>(m + 1, vector<Bool>(n + 1, false));
dp[0][0] = true;
for (int j = 1; j <= n; ++j) {
dp[0][j] = (dp[0][j - 1] && (s3[j - 1] == s2[j - 1]));
}
for (int i = 1; i <= m; ++i) {
dp[i][0] = (dp[i - 1][0] && (s3[i - 1] == s1[i - 1]));
}
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
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])); //
}
}
return dp[m][n];
}
};
// 1D-DP
class Solution2 {
using Bool = uint8_t;
public:
bool isInterleave(const string &s1, const string &s2, const string &s3) {
const int m = s1.size(), n = s2.size();
// Guard
if (s3.size() != m + n) return false;
// DP
auto prev = vector<Bool>(n + 1, false);
auto curr = vector<Bool>(n + 1, false);
curr[0] = true;
for (int j = 1; j <= n; ++j) {
curr[j] = (curr[j - 1] && (s3[j - 1] == s2[j - 1]));
}
for (int i = 1; i <= m; ++i) {
swap(curr, prev);
curr[0] = (prev[0] && (s3[i - 1] == s1[i - 1]));
for (int j = 1; j <= n; ++j) {
curr[j] = (prev[j] && (s3[i + j - 1] == s1[i - 1])) || //
(curr[j - 1] && (s3[i + j - 1] == s2[j - 1])); //
}
}
return curr[n];
}
};