Skip to content

Commit 0eb6167

Browse files
committed
Longest substring without repeating characters
1 parent 295edaa commit 0eb6167

File tree

2 files changed

+306
-0
lines changed

2 files changed

+306
-0
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// 3. Longest substring without repeating characters
2+
// Topics: 'Hash Table', 'String', 'Sliding window'
3+
// Level: 'Medium'
4+
5+
// Given a string s, find the length of the longest
6+
7+
// without duplicate characters.
8+
9+
// Example 1:
10+
11+
// Input: s = "abcabcbb"
12+
// Output: 3
13+
// Explanation: The answer is "abc", with the length of 3. Note that "bca" and "cab" are also correct answers.
14+
15+
// Example 2:
16+
17+
// Input: s = "bbbbb"
18+
// Output: 1
19+
// Explanation: The answer is "b", with the length of 1.
20+
21+
// Example 3:
22+
23+
// Input: s = "pwwkew"
24+
// Output: 3
25+
// Explanation: The answer is "wke", with the length of 3.
26+
// Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.
27+
28+
// Constraints:
29+
30+
// 0 <= s.length <= 5 * 104
31+
// s consists of English letters, digits, symbols and spaces.
32+
33+
package longestsubstringwithoutrepeatingcharacters
34+
35+
func lengthOfLongestSubstring(s string) int {
36+
m := map[byte]int{}
37+
var _max int
38+
var start int
39+
for i := 0; i < len(s); i++ {
40+
j, ok := m[s[i]]
41+
if ok {
42+
for start <= j {
43+
delete(m, s[start])
44+
start++
45+
}
46+
}
47+
m[s[i]] = i
48+
49+
_max = max(_max, len(m))
50+
}
51+
return _max
52+
}
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
package longestsubstringwithoutrepeatingcharacters
2+
3+
import "testing"
4+
5+
func TestLengthOfLongestSubstring_BasicCases(t *testing.T) {
6+
tests := []struct {
7+
name string
8+
input string
9+
expected int
10+
}{
11+
{
12+
name: "example 1 - multiple unique substrings",
13+
input: "abcabcbb",
14+
expected: 3,
15+
},
16+
{
17+
name: "example 2 - all same characters",
18+
input: "bbbbb",
19+
expected: 1,
20+
},
21+
{
22+
name: "example 3 - mixed pattern",
23+
input: "pwwkew",
24+
expected: 3,
25+
},
26+
}
27+
28+
for _, tt := range tests {
29+
t.Run(tt.name, func(t *testing.T) {
30+
result := lengthOfLongestSubstring(tt.input)
31+
if result != tt.expected {
32+
t.Errorf("lengthOfLongestSubstring(%q) = %d, want %d", tt.input, result, tt.expected)
33+
}
34+
})
35+
}
36+
}
37+
38+
func TestLengthOfLongestSubstring_EdgeCases(t *testing.T) {
39+
tests := []struct {
40+
name string
41+
input string
42+
expected int
43+
}{
44+
{
45+
name: "empty string",
46+
input: "",
47+
expected: 0,
48+
},
49+
{
50+
name: "single character",
51+
input: "a",
52+
expected: 1,
53+
},
54+
{
55+
name: "two same characters",
56+
input: "aa",
57+
expected: 1,
58+
},
59+
{
60+
name: "two different characters",
61+
input: "ab",
62+
expected: 2,
63+
},
64+
}
65+
66+
for _, tt := range tests {
67+
t.Run(tt.name, func(t *testing.T) {
68+
result := lengthOfLongestSubstring(tt.input)
69+
if result != tt.expected {
70+
t.Errorf("lengthOfLongestSubstring(%q) = %d, want %d", tt.input, result, tt.expected)
71+
}
72+
})
73+
}
74+
}
75+
76+
func TestLengthOfLongestSubstring_AllUniqueCharacters(t *testing.T) {
77+
tests := []struct {
78+
name string
79+
input string
80+
expected int
81+
}{
82+
{
83+
name: "all unique lowercase",
84+
input: "abcdefg",
85+
expected: 7,
86+
},
87+
{
88+
name: "all unique mixed case",
89+
input: "abcABC",
90+
expected: 6,
91+
},
92+
{
93+
name: "all unique with numbers",
94+
input: "abc123",
95+
expected: 6,
96+
},
97+
}
98+
99+
for _, tt := range tests {
100+
t.Run(tt.name, func(t *testing.T) {
101+
result := lengthOfLongestSubstring(tt.input)
102+
if result != tt.expected {
103+
t.Errorf("lengthOfLongestSubstring(%q) = %d, want %d", tt.input, result, tt.expected)
104+
}
105+
})
106+
}
107+
}
108+
109+
func TestLengthOfLongestSubstring_RepeatingPatterns(t *testing.T) {
110+
tests := []struct {
111+
name string
112+
input string
113+
expected int
114+
}{
115+
{
116+
name: "alternating pattern",
117+
input: "abba",
118+
expected: 2,
119+
},
120+
{
121+
name: "pattern at end",
122+
input: "abcda",
123+
expected: 4,
124+
},
125+
{
126+
name: "pattern at beginning",
127+
input: "aabcdef",
128+
expected: 6,
129+
},
130+
{
131+
name: "complex repeating",
132+
input: "tmmzuxt",
133+
expected: 5,
134+
},
135+
}
136+
137+
for _, tt := range tests {
138+
t.Run(tt.name, func(t *testing.T) {
139+
result := lengthOfLongestSubstring(tt.input)
140+
if result != tt.expected {
141+
t.Errorf("lengthOfLongestSubstring(%q) = %d, want %d", tt.input, result, tt.expected)
142+
}
143+
})
144+
}
145+
}
146+
147+
func TestLengthOfLongestSubstring_SpecialCharacters(t *testing.T) {
148+
tests := []struct {
149+
name string
150+
input string
151+
expected int
152+
}{
153+
{
154+
name: "with spaces",
155+
input: "a b c a",
156+
expected: 3,
157+
},
158+
{
159+
name: "with symbols",
160+
input: "!@#$%!",
161+
expected: 5,
162+
},
163+
{
164+
name: "mixed symbols and letters",
165+
input: "a!b@c#a",
166+
expected: 6,
167+
},
168+
{
169+
name: "digits only",
170+
input: "0123401",
171+
expected: 5,
172+
},
173+
}
174+
175+
for _, tt := range tests {
176+
t.Run(tt.name, func(t *testing.T) {
177+
result := lengthOfLongestSubstring(tt.input)
178+
if result != tt.expected {
179+
t.Errorf("lengthOfLongestSubstring(%q) = %d, want %d", tt.input, result, tt.expected)
180+
}
181+
})
182+
}
183+
}
184+
185+
func TestLengthOfLongestSubstring_LongStrings(t *testing.T) {
186+
tests := []struct {
187+
name string
188+
input string
189+
expected int
190+
}{
191+
{
192+
name: "long repeating",
193+
input: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
194+
expected: 1,
195+
},
196+
{
197+
name: "long unique then repeat",
198+
input: "abcdefghijklmnopqrstuvwxyza",
199+
expected: 26,
200+
},
201+
{
202+
name: "alphabet repeated",
203+
input: "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
204+
expected: 26,
205+
},
206+
}
207+
208+
for _, tt := range tests {
209+
t.Run(tt.name, func(t *testing.T) {
210+
result := lengthOfLongestSubstring(tt.input)
211+
if result != tt.expected {
212+
t.Errorf("lengthOfLongestSubstring(%q) = %d, want %d", tt.input, result, tt.expected)
213+
}
214+
})
215+
}
216+
}
217+
218+
func TestLengthOfLongestSubstring_WindowShifting(t *testing.T) {
219+
tests := []struct {
220+
name string
221+
input string
222+
expected int
223+
}{
224+
{
225+
name: "window shifts forward",
226+
input: "abcdefabc",
227+
expected: 6,
228+
},
229+
{
230+
name: "multiple window shifts",
231+
input: "abcabcbb",
232+
expected: 3,
233+
},
234+
{
235+
name: "immediate repeat",
236+
input: "aab",
237+
expected: 2,
238+
},
239+
{
240+
name: "dvdf case",
241+
input: "dvdf",
242+
expected: 3,
243+
},
244+
}
245+
246+
for _, tt := range tests {
247+
t.Run(tt.name, func(t *testing.T) {
248+
result := lengthOfLongestSubstring(tt.input)
249+
if result != tt.expected {
250+
t.Errorf("lengthOfLongestSubstring(%q) = %d, want %d", tt.input, result, tt.expected)
251+
}
252+
})
253+
}
254+
}

0 commit comments

Comments
 (0)