Skip to content

Commit 7f1c280

Browse files
feat(revision): add Day 02 - Strings (Longest Substring, Minimum Window) — detailed solutions
1 parent a748c54 commit 7f1c280

2 files changed

Lines changed: 156 additions & 0 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// 01_longest_substring_without_repeating_characters.cpp
2+
// Problem: Longest Substring Without Repeating Characters
3+
// LeetCode: https://leetcode.com/problems/longest-substring-without-repeating-characters/
4+
// Author: DeveloperViraj (curated DSA set for Hacktoberfest 2025)
5+
// Compile: g++ -std=c++17 01_longest_substring_without_repeating_characters.cpp -o 01_longest_substring
6+
// Run: ./01_longest_substring
7+
//
8+
// Summary:
9+
// Given a string, find the length of the longest substring without repeating characters.
10+
//
11+
// Approach (sliding window + last-seen index):
12+
// Use two indices (windowStart and windowEnd) and a map of last-seen indices for characters.
13+
// Expand the windowEnd and if the current character was seen inside the current window,
14+
// move windowStart to lastSeenIndex + 1. Update the maximum window length as you go.
15+
//
16+
// Time Complexity: O(n) where n = length of string (each char visited at most twice).
17+
// Space Complexity: O(min(n, charset)) for the hash map of last seen indices.
18+
19+
#include <iostream>
20+
#include <string>
21+
#include <unordered_map>
22+
using namespace std;
23+
24+
int lengthOfLongestUniqueSubstring(const string &s) {
25+
unordered_map<char,int> lastSeen;
26+
int maxLength = 0;
27+
int windowStart = 0;
28+
29+
for (int windowEnd = 0; windowEnd < (int)s.size(); ++windowEnd) {
30+
char currentChar = s[windowEnd];
31+
if (lastSeen.find(currentChar) != lastSeen.end()) {
32+
// If this character appeared inside current window, move start
33+
if (lastSeen[currentChar] >= windowStart) {
34+
windowStart = lastSeen[currentChar] + 1;
35+
}
36+
}
37+
lastSeen[currentChar] = windowEnd;
38+
int windowLength = windowEnd - windowStart + 1;
39+
if (windowLength > maxLength) maxLength = windowLength;
40+
}
41+
return maxLength;
42+
}
43+
44+
int main() {
45+
cout << "Longest Substring Without Repeating Characters\n";
46+
cout << "Enter a single-line string and press Enter:\n";
47+
string input;
48+
if (!getline(cin, input)) return 0;
49+
50+
int result = lengthOfLongestUniqueSubstring(input);
51+
cout << "Length: " << result << "\n";
52+
return 0;
53+
}
54+
55+
/*
56+
Example:
57+
Input:
58+
abcabcbb
59+
Output:
60+
Length: 3 (substring "abc")
61+
*/
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// 02_minimum_window_substring.cpp
2+
// Problem: Minimum Window Substring
3+
// LeetCode: https://leetcode.com/problems/minimum-window-substring/
4+
// Author: DeveloperViraj (curated DSA set for Hacktoberfest 2025)
5+
// Compile: g++ -std=c++17 02_minimum_window_substring.cpp -o 02_minimum_window_substring
6+
// Run: ./02_minimum_window_substring
7+
//
8+
// Summary:
9+
// Given strings S and T, find the smallest substring in S that contains all characters of T
10+
// (including multiplicity). If no such window exists, return an empty string.
11+
//
12+
// Approach (sliding window + frequency maps):
13+
// 1. Build a frequency map for characters required by T.
14+
// 2. Expand 'right' pointer: add chars to current window counts.
15+
// 3. When the window satisfies all required counts (formed == required), try to shrink 'left'
16+
// to minimize the window while still satisfying the requirement.
17+
// 4. Track best (smallest) window found during the process.
18+
//
19+
// Time Complexity: O(|S| + |T|) average (each char processed a constant number of times).
20+
// Space Complexity: O(CHARSET) or O(|T|) for maps.
21+
22+
#include <iostream>
23+
#include <string>
24+
#include <unordered_map>
25+
#include <climits>
26+
using namespace std;
27+
28+
string minWindow(const string &source, const string &target) {
29+
if (target.empty() || source.empty() || source.size() < target.size()) return "";
30+
31+
unordered_map<char,int> need;
32+
for (char c : target) need[c]++;
33+
34+
int required = need.size(); // distinct characters needed
35+
int formed = 0; // how many distinct characters currently satisfy required count
36+
unordered_map<char,int> windowCounts;
37+
38+
int left = 0, right = 0;
39+
int bestLeft = 0;
40+
int bestLen = INT_MAX;
41+
42+
while (right < (int)source.size()) {
43+
char c = source[right];
44+
windowCounts[c]++;
45+
46+
// If current char count matches the required count, we've satisfied one distinct char
47+
if (need.count(c) && windowCounts[c] == need[c]) {
48+
formed++;
49+
}
50+
51+
// When all required chars are satisfied, try to shrink from the left
52+
while (left <= right && formed == required) {
53+
if (right - left + 1 < bestLen) {
54+
bestLen = right - left + 1;
55+
bestLeft = left;
56+
}
57+
58+
char leftChar = source[left];
59+
windowCounts[leftChar]--;
60+
if (need.count(leftChar) && windowCounts[leftChar] < need[leftChar]) {
61+
formed--;
62+
}
63+
left++;
64+
}
65+
66+
right++;
67+
}
68+
69+
if (bestLen == INT_MAX) return "";
70+
return source.substr(bestLeft, bestLen);
71+
}
72+
73+
int main() {
74+
cout << "Minimum Window Substring\n";
75+
cout << "Input format (two lines):\nS\nT\n\nEnter S (source string) and T (target string) each on a new line:\n";
76+
77+
string S, T;
78+
if (!getline(cin, S)) return 0;
79+
if (!getline(cin, T)) return 0;
80+
81+
string answer = minWindow(S, T);
82+
if (answer.empty()) {
83+
cout << "No valid window found\n";
84+
} else {
85+
cout << "Minimum window: " << answer << "\n";
86+
}
87+
return 0;
88+
}
89+
90+
/*
91+
Example:
92+
S = "ADOBECODEBANC"
93+
T = "ABC"
94+
Output: "BANC"
95+
*/

0 commit comments

Comments
 (0)