Skip to content

Commit 6bce988

Browse files
committed
refactor: Use tests.h in 2pointers Sliding Window
1 parent 0c1489f commit 6bce988

File tree

1 file changed

+27
-204
lines changed

1 file changed

+27
-204
lines changed
Lines changed: 27 additions & 204 deletions
Original file line numberDiff line numberDiff line change
@@ -1,233 +1,56 @@
11
/**
2-
* Longest Substring Without Repeating Characters
3-
* ==============================================
4-
*
5-
* Leetcode: [3. Longest Substring Without Repeating Characters][lc3]
6-
*
7-
* Given a string s, find the length of the longest substring without
8-
* repeating characters.
9-
*
10-
* Tags: #strings, #medium
11-
*
12-
* Example 1:
13-
*
14-
* Input: s = "abcabcbb"
15-
* Output: 3
16-
* Explanation: The answer is "abc", with the length of 3.
17-
*
18-
* Example 2:
19-
*
20-
* Input: s = "bbbbb"
21-
* Output: 1
22-
* Explanation: The answer is "b", with the length of 1.
23-
*
24-
* Example 3:
25-
*
26-
* Input: s = "pwwkew"
27-
* Output: 3
28-
* Explanation: The answer is "wke", with the length of 3.
29-
*
30-
* Notice that the answer must be a substring, "pwke" is a subsequence and not
31-
* a substring.
32-
*
33-
* Solution
34-
* --------
2+
* Two pointers - sliding window technique - 01
3+
* ============================================
354
*
365
* Refer:
376
*
38-
* [sliding window technique][lcdi1]
39-
* [Optimized sliding window solution][ea1]
40-
*
41-
* [lc3]: https://leetcode.com/problems/longest-substring-without-repeating-characters/
42-
* [lcdi1]: https://discuss.leetcode.com/topic/30941/here-is-a-10-line-template-that-can-solve-most-substring-problems
43-
* [ea1]: https://www.enjoyalgorithms.com/blog/longest-substring-without-repeating-characters
44-
*/
45-
46-
#include <bits/stdc++.h>
47-
48-
using namespace std;
49-
50-
/* ===========================================================================
51-
* Test helpers
52-
* ===========================================================================
7+
* https://www.geeksforgeeks.org/window-sliding-technique/
8+
* https://discuss.leetcode.com/topic/30941/here-is-a-10-line-template-that-can-solve-most-substring-problems
539
*/
54-
class _00_test
55-
{
56-
public:
57-
_00_test(const string &name) : name(name) {}
58-
59-
string getName(void) const { return name; }
60-
61-
virtual int maxLenUniqCharsSubstr(const string &str) = 0;
6210

63-
private:
64-
string name;
65-
};
11+
#include "tests.h"
6612

6713
/* ===========================================================================
6814
* Algorithms implementation
6915
* ===========================================================================
7016
*/
7117

72-
/* TC : O(n^3)
73-
* SC : O(1)
74-
*/
75-
class _01_brute_force : public _00_test
76-
{
77-
public:
78-
_01_brute_force()
79-
: _00_test("Longest Substring Without Repeating Characters brute "
80-
"force")
81-
{
82-
}
83-
84-
int maxLenUniqCharsSubstr(const string &s) override
85-
{
86-
auto is_uniq = [](string s, int b, int e) -> bool {
87-
vector m(128, 0);
88-
for (int k = b; k <= e; k++) {
89-
if (m[s[k]]++) return false;
90-
}
91-
return true;
92-
};
93-
94-
int n = static_cast<int>(s.size());
95-
int d = 0;
96-
for (int b = 0; b < n; b++)
97-
for (int e = b; e < n; e++)
98-
if (is_uniq(s, b, e)) d = max(d, e - b + 1);
99-
return d;
100-
}
101-
};
102-
103-
/* TC : O(n^2)
104-
* SC : O(1)
105-
*/
106-
class _02_sliding_window : public _00_test
107-
{
108-
public:
109-
_02_sliding_window()
110-
: _00_test("Longest Substring Without Repeating Characters "
111-
"sliding window")
112-
{
113-
}
114-
115-
int maxLenUniqCharsSubstr(const string &s) override
116-
{
117-
int n = static_cast<int>(s.size());
118-
int b = 0, e = 0, d = 0;
119-
while (b < n) {
120-
vector m(128, 0);
121-
e = b;
122-
while (e < n && !m[s[e]]) {
123-
d = max(d, e - b + 1);
124-
m[s[e++]]++;
125-
}
126-
b++;
127-
}
128-
return d;
129-
}
130-
};
131-
13218
/* TC : O(n)
13319
* SC : O(1)
13420
*/
135-
class _03_optmized_sliding_window : public _00_test
136-
{
137-
public:
138-
_03_optmized_sliding_window()
139-
: _00_test("Longest Substring Without Repeating Characters "
140-
"optimized sliding window")
141-
{
142-
}
14321

144-
int maxLenUniqCharsSubstr(const string &s) override
145-
{
146-
int n = static_cast<int>(s.size());
147-
vector m(128, 0);
148-
int b = 0, e = 0, d = 0;
149-
while (b < n && e < n) {
150-
if (!m[s[e]]++) {
151-
e++;
152-
d = max(d, e - b);
153-
} else
154-
m[s[b++]] = 0;
155-
}
156-
return d;
157-
}
158-
};
22+
#define _2p_sw_maxSubstrUniqChars_desc "Two Pointers - Sliding Window - " \
23+
"Longest Substring Without Repeating Characters"
15924

160-
/* TC : O(n)
161-
* SC : O(1)
162-
*/
163-
class _04_counter_sliding_window : public _00_test
25+
int maxSubstrUniqChars(const string &s)
16426
{
165-
public:
166-
_04_counter_sliding_window()
167-
: _00_test("Longest Substring Without Repeating Characters "
168-
"counter sliding window")
169-
{
170-
}
171-
172-
int maxLenUniqCharsSubstr(const string &s) override
173-
{
174-
vector<int> m(128, 0);
175-
int c = 0, b = 0, e = 0, d = 0;
176-
while (e < static_cast<int>(s.size())) {
177-
if (m[s[e++]]++) c++;
178-
while (c)
179-
if (m[s[b++]]-- > 1) c--;
180-
d = max(d, e - b);
181-
}
182-
return d;
183-
}
184-
};
27+
int n = size(s);
28+
int l = 0, r = 0, d = 0;
29+
vi_v(m, 128, 0);
30+
while (l < n && r < n) {
31+
if (!m[s[r]]++) r++, d = max(d, r - l);
32+
else m[s[l++]] = 0;
33+
}
34+
return d;
35+
}
18536

18637
/* ===========================================================================
18738
* Test code
18839
* ===========================================================================
18940
*/
190-
void test_impl(const vector<string> &ip, const vector<int> &op,
191-
shared_ptr<_00_test> f)
192-
{
193-
for (size_t i = 0; i < ip.size(); i++) {
194-
int t = f->maxLenUniqCharsSubstr(ip[i]);
195-
if (t != op[i]) {
196-
cerr << f->getName() << " test failed: "
197-
<< "expected " << op[i] << ", actual " << t
198-
<< "." << endl;
199-
exit(1);
200-
}
201-
202-
if (getenv("SHOW_TEST_OUTPUT"))
203-
cout << " test-" << i << ": "
204-
<< "input: str = " << ip[i]
205-
<< " output: maxLen = " << t << "\n";
41+
#define _2p_sw_maxSubstrUniqChars_check(i, e) \
42+
{ \
43+
int a = maxSubstrUniqChars(i); \
44+
CHECK_EQ(e, a); \
45+
SHOW_OUTPUT(i, a); \
20646
}
207-
}
20847

209-
int main(int, char **)
48+
TEST(maxSubstrUniqChars, _2p_sw_maxSubstrUniqChars_desc)
21049
{
21150
vector<string> ip{"", "abcabcbb", "bbbbb", "pwwkew"};
212-
21351
vector<int> op{0, 3, 1, 3};
214-
215-
vector<shared_ptr<_00_test>> impls{
216-
make_shared<_01_brute_force>(),
217-
make_shared<_02_sliding_window>(),
218-
make_shared<_03_optmized_sliding_window>(),
219-
make_shared<_04_counter_sliding_window>(),
220-
};
221-
222-
for (size_t i = 0; i < impls.size(); i++) {
223-
if (getenv("SHOW_TEST_OUTPUT"))
224-
cout << "Testing implementation " << i + 1 << " "
225-
<< impls[i]->getName() << "\n";
226-
227-
test_impl(ip, op, impls[i]);
228-
}
229-
230-
cout << "Executed " << impls.size() << " implementations"
231-
<< " with " << ip.size() << " tests." << endl;
232-
return 0;
52+
int n = size(ip);
53+
fii (i, n) _2p_sw_maxSubstrUniqChars_check(ip[i], op[i]);
23354
}
55+
56+
INIT_TEST_MAIN();

0 commit comments

Comments
 (0)