Skip to content

Commit e41888e

Browse files
author
Carlos Gutierrez
committed
Complete documentation system with 81 comprehensive notes and updated README index
1 parent fe26a41 commit e41888e

File tree

81 files changed

+10035
-82
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+10035
-82
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Created by https://www.toptal.com/developers/gitignore/api/node,java,python,c++
22
# Edit at https://www.toptal.com/developers/gitignore?templates=node,java,python,c++
33
.cursor*
4-
*src/notes*
4+
# *src/notes*
55
*backup/
66
./src/notes/
77
*sync_leetcode.sh

README.md

Lines changed: 81 additions & 81 deletions
Large diffs are not rendered by default.

src/notes/001_two_sum.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Two Sum
2+
3+
[![Problem 1](https://img.shields.io/badge/Problem-1-blue?style=for-the-badge&logo=leetcode)](https://leetcode.com/problems/two-sum/)
4+
[![Difficulty](https://img.shields.io/badge/Difficulty-Easy-green?style=for-the-badge)](https://leetcode.com/problemset/?difficulty=EASY)
5+
[![LeetCode](https://img.shields.io/badge/LeetCode-View%20Problem-orange?style=for-the-badge&logo=leetcode)](https://leetcode.com/problems/two-sum/)
6+
7+
**Problem Number:** [1](https://leetcode.com/problems/two-sum/)
8+
**Difficulty:** [Easy](https://leetcode.com/problemset/?difficulty=EASY)
9+
**Category:** Array, Hash Table
10+
**LeetCode Link:** [https://leetcode.com/problems/two-sum/](https://leetcode.com/problems/two-sum/)
11+
12+
## Problem Description
13+
14+
Given an array of integers `nums` and an integer `target`, return indices of the two numbers such that they add up to `target`.
15+
16+
You may assume that each input would have exactly one solution, and you may not use the same element twice.
17+
18+
You can return the answer in any order.
19+
20+
**Example 1:**
21+
```
22+
Input: nums = [2,7,11,15], target = 9
23+
Output: [0,1]
24+
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].
25+
```
26+
27+
**Example 2:**
28+
```
29+
Input: nums = [3,2,4], target = 6
30+
Output: [1,2]
31+
```
32+
33+
**Example 3:**
34+
```
35+
Input: nums = [3,3], target = 6
36+
Output: [0,1]
37+
```
38+
39+
**Constraints:**
40+
- `2 <= nums.length <= 10^4`
41+
- `-10^9 <= nums[i] <= 10^9`
42+
- `-10^9 <= target <= 10^9`
43+
- Only one valid answer exists.
44+
45+
## My Approach
46+
47+
I used a **Hash Table (Dictionary)** approach to solve this problem efficiently. The key insight is to use a hash map to store previously seen numbers and their indices, allowing us to find the complement in O(1) time.
48+
49+
**Algorithm:**
50+
1. Create an empty hash map to store numbers and their indices
51+
2. Iterate through the array once
52+
3. For each number, calculate its complement (target - current_number)
53+
4. Check if the complement exists in the hash map
54+
5. If found, return the current index and the complement's index
55+
6. If not found, add the current number and its index to the hash map
56+
57+
## Solution
58+
59+
The solution uses a hash table approach to achieve O(n) time complexity. See the implementation in the [solution file](../exercises/1.two-sum.py).
60+
61+
**Key Points:**
62+
- Uses a hash map for O(1) lookup time
63+
- Only requires a single pass through the array
64+
- Handles edge cases appropriately
65+
- Returns indices in the order [current_index, complement_index]
66+
67+
## Time & Space Complexity
68+
69+
**Time Complexity:** O(n)
70+
- We iterate through the array once: O(n)
71+
- Hash map operations (insertion and lookup) are O(1) on average
72+
- Total: O(n)
73+
74+
**Space Complexity:** O(n)
75+
- In the worst case, we might need to store all n elements in the hash map
76+
- This occurs when the solution is found at the end of the array
77+
78+
## Key Insights
79+
80+
1. **Hash Table Efficiency:** Using a hash table allows us to achieve O(n) time complexity instead of the O(n²) that would result from a brute force approach with nested loops.
81+
82+
2. **Single Pass Solution:** We can find the solution in just one iteration through the array by storing previously seen numbers and checking for complements.
83+
84+
3. **Complement Strategy:** Instead of looking for two numbers that sum to target, we look for one number and its complement (target - number).
85+
86+
4. **Edge Case Handling:** The solution includes proper handling of edge cases like empty arrays and arrays with fewer than 2 elements.
87+
88+
5. **No Duplicate Usage:** The algorithm naturally avoids using the same element twice because we check for the complement before adding the current element to the hash map.
89+
90+
## Mistakes Made
91+
92+
1. **Initial Edge Case Over-engineering:** The solution includes edge cases for arrays with 0, 1, or 2 elements, which might be unnecessary given the problem constraints (array length ≥ 2).
93+
94+
2. **Return Order:** The solution returns [current_index, complement_index], but the problem allows returning the answer in any order.
95+
96+
## Related Problems
97+
98+
- **Two Sum II - Input Array Is Sorted** (Problem 167): Similar problem but with a sorted array, allowing for a two-pointer approach
99+
- **Two Sum BST** (Problem 653): Finding two nodes in a BST that sum to target
100+
- **Three Sum** (Problem 15): Extension to finding three numbers that sum to zero
101+
- **Four Sum** (Problem 18): Further extension to finding four numbers that sum to target
102+
103+
## Alternative Approaches
104+
105+
1. **Brute Force:** O(n²) time complexity with nested loops
106+
2. **Two Pointers:** Only works for sorted arrays, O(n log n) due to sorting
107+
3. **Binary Search:** Only applicable for sorted arrays
108+
109+
---
110+
111+
[![Back to Index](../../README.md#-problem-index)](../../README.md#-problem-index) | [![View Solution](../exercises/1.two-sum.py)](../exercises/1.two-sum.py)
112+
113+
*Note: This is a fundamental problem that introduces the hash table optimization pattern, commonly used in array and string problems.*

src/notes/002_add_two_numbers.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Add Two Numbers
2+
3+
[![Problem 2](https://img.shields.io/badge/Problem-2-blue?style=for-the-badge&logo=leetcode)](https://leetcode.com/problems/add-two-numbers/)
4+
[![Difficulty](https://img.shields.io/badge/Difficulty-Medium-orange?style=for-the-badge)](https://leetcode.com/problemset/?difficulty=MEDIUM)
5+
[![LeetCode](https://img.shields.io/badge/LeetCode-View%20Problem-orange?style=for-the-badge&logo=leetcode)](https://leetcode.com/problems/add-two-numbers/)
6+
7+
**Problem Number:** [2](https://leetcode.com/problems/add-two-numbers/)
8+
**Difficulty:** [Medium](https://leetcode.com/problemset/?difficulty=MEDIUM)
9+
**Category:** Linked List, Math, Recursion
10+
**LeetCode Link:** [https://leetcode.com/problems/add-two-numbers/](https://leetcode.com/problems/add-two-numbers/)
11+
12+
## Problem Description
13+
14+
You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the two numbers and return the sum as a linked list.
15+
16+
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
17+
18+
**Example 1:**
19+
```
20+
Input: l1 = [2,4,3], l2 = [5,6,4]
21+
Output: [7,0,8]
22+
Explanation: 342 + 465 = 807
23+
```
24+
25+
**Example 2:**
26+
```
27+
Input: l1 = [0], l2 = [0]
28+
Output: [0]
29+
```
30+
31+
**Example 3:**
32+
```
33+
Input: l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
34+
Output: [8,9,9,9,0,0,0,1]
35+
```
36+
37+
**Constraints:**
38+
- The number of nodes in each linked list is in the range [1, 100]
39+
- 0 <= Node.val <= 9
40+
- It is guaranteed that the list represents a number that does not have leading zeros
41+
42+
## My Approach
43+
44+
I used an **iterative approach** to simulate the manual addition process we learned in elementary school. The key insight is to process both linked lists digit by digit, maintaining a carry value, and building the result linked list as we go.
45+
46+
**Algorithm:**
47+
1. Initialize a carry variable to 0
48+
2. Create a dummy head node for the result linked list
49+
3. Iterate through both linked lists simultaneously:
50+
- Extract the current digit from each list (0 if list is exhausted)
51+
- Add the digits along with the carry
52+
- Calculate the new carry and the digit to store
53+
- Create a new node with the calculated digit
54+
- Append it to the result list
55+
4. If there's still a carry after processing all digits, create a final node
56+
5. Return the head of the result linked list
57+
58+
## Solution
59+
60+
The solution uses an iterative approach to add two numbers represented as linked lists. See the implementation in the [solution file](../exercises/2.add-two-numbers.py).
61+
62+
**Key Points:**
63+
- Processes both lists simultaneously, handling different lengths
64+
- Maintains a carry value throughout the addition process
65+
- Builds the result linked list incrementally
66+
- Handles the final carry if it exists
67+
- Returns the result in reverse order (least significant digit first)
68+
69+
## Time & Space Complexity
70+
71+
**Time Complexity:** O(max(M, N))
72+
- We iterate through both linked lists once
73+
- M and N are the lengths of the input linked lists
74+
- Each iteration performs constant time operations
75+
76+
**Space Complexity:** O(max(M, N))
77+
- We create a new linked list to store the result
78+
- The result can be at most max(M, N) + 1 digits long (due to carry)
79+
- We use a constant amount of extra space for variables
80+
81+
## Key Insights
82+
83+
1. **Reverse Order Advantage:** The fact that digits are stored in reverse order makes the addition process straightforward - we can process from left to right, just like manual addition.
84+
85+
2. **Carry Management:** The carry must be tracked and added to the next position, similar to how we learned addition in school.
86+
87+
3. **Different Lengths:** The solution handles cases where the input lists have different lengths by treating missing digits as 0.
88+
89+
4. **Final Carry:** After processing all digits, if there's still a carry, it becomes the most significant digit in the result.
90+
91+
5. **Linked List Construction:** Building the result linked list incrementally is more efficient than converting to integers and back.
92+
93+
6. **No Leading Zeros:** The problem guarantees no leading zeros in input, but we need to handle the case where the result might have a leading zero (like 0 + 0 = 0).
94+
95+
## Mistakes Made
96+
97+
1. **Carry Calculation:** The initial approach of converting the sum to a string to extract carry and digit is inefficient. A more efficient approach would be to use integer division and modulo operations.
98+
99+
2. **Variable Naming:** The variable names could be more descriptive to improve code readability.
100+
101+
3. **Edge Case Handling:** Need to ensure proper handling when one list is longer than the other.
102+
103+
## Related Problems
104+
105+
- **Add Two Numbers II** (Problem 445): Similar problem but digits are stored in forward order
106+
- **Multiply Strings** (Problem 43): Multiplying two numbers represented as strings
107+
- **Plus One** (Problem 66): Adding one to a number represented as an array
108+
- **Add Binary** (Problem 67): Adding two binary strings
109+
- **Add Strings** (Problem 415): Adding two numbers represented as strings
110+
111+
## Alternative Approaches
112+
113+
1. **Recursive Solution:** Can be solved recursively by processing one digit at a time
114+
2. **Convert to Integer:** Convert linked lists to integers, add them, then convert back (not recommended due to potential overflow)
115+
3. **Stack-based:** Use stacks to reverse the order and then add (useful for forward order problems)
116+
117+
## Common Pitfalls
118+
119+
1. **Forgetting Final Carry:** Always check if there's a carry after processing all digits
120+
2. **Null Pointer Exceptions:** Ensure proper null checks when accessing list nodes
121+
3. **Memory Management:** Be careful not to lose references when building the result list
122+
4. **Overflow:** While the problem constraints prevent integer overflow, it's good practice to consider it
123+
124+
---
125+
126+
[![Back to Index](../../README.md#-problem-index)](../../README.md#-problem-index) | [![View Solution](../exercises/2.add-two-numbers.py)](../exercises/2.add-two-numbers.py)
127+
128+
*Note: This is a fundamental linked list problem that teaches the importance of careful iteration and carry management in mathematical operations.*
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# Longest Substring Without Repeating Characters
2+
3+
[![Problem 3](https://img.shields.io/badge/Problem-3-blue?style=for-the-badge&logo=leetcode)](https://leetcode.com/problems/longest-substring-without-repeating-characters/)
4+
[![Difficulty](https://img.shields.io/badge/Difficulty-Medium-orange?style=for-the-badge)](https://leetcode.com/problemset/?difficulty=MEDIUM)
5+
[![LeetCode](https://img.shields.io/badge/LeetCode-View%20Problem-orange?style=for-the-badge&logo=leetcode)](https://leetcode.com/problems/longest-substring-without-repeating-characters/)
6+
7+
**Problem Number:** [3](https://leetcode.com/problems/longest-substring-without-repeating-characters/)
8+
**Difficulty:** [Medium](https://leetcode.com/problemset/?difficulty=MEDIUM)
9+
**Category:** Hash Table, String, Sliding Window
10+
**LeetCode Link:** [https://leetcode.com/problems/longest-substring-without-repeating-characters/](https://leetcode.com/problems/longest-substring-without-repeating-characters/)
11+
12+
## Problem Description
13+
14+
Given a string `s`, find the length of the longest substring without repeating characters.
15+
16+
**Example 1:**
17+
```
18+
Input: s = "abcabcbb"
19+
Output: 3
20+
Explanation: The answer is "abc", with the length of 3.
21+
```
22+
23+
**Example 2:**
24+
```
25+
Input: s = "bbbbb"
26+
Output: 1
27+
Explanation: The answer is "b", with the length of 1.
28+
```
29+
30+
**Example 3:**
31+
```
32+
Input: s = "pwwkew"
33+
Output: 3
34+
Explanation: The answer is "wke", with the length of 3.
35+
Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.
36+
```
37+
38+
**Constraints:**
39+
- `0 <= s.length <= 5 * 10^4`
40+
- `s` consists of English letters, digits, symbols and spaces
41+
42+
## My Approach
43+
44+
I used a **Sliding Window** approach with a hash table to track characters in the current window. The key insight is to maintain a window of unique characters and expand/shrink it as needed.
45+
46+
**Algorithm:**
47+
1. Initialize two pointers (i, j) at the beginning of the string
48+
2. Use a hash table to track characters in the current window
49+
3. Expand the window by moving the right pointer (j) when we encounter a new character
50+
4. Shrink the window by moving the left pointer (i) when we encounter a duplicate
51+
5. Keep track of the maximum window size seen so far
52+
6. Return the maximum length found
53+
54+
## Solution
55+
56+
The solution uses a sliding window approach with hash table optimization. See the implementation in the [solution file](../exercises/3.longest-substring-without-repeating-characters.py).
57+
58+
**Key Points:**
59+
- Uses two pointers to maintain a sliding window
60+
- Hash table tracks characters in the current window
61+
- Expands window when encountering new characters
62+
- Shrinks window when encountering duplicates
63+
- Tracks maximum window size throughout the process
64+
65+
## Time & Space Complexity
66+
67+
**Time Complexity:** O(n)
68+
- We traverse the string once with two pointers
69+
- Hash table operations are O(1) on average
70+
- Each character is visited at most twice (once by each pointer)
71+
72+
**Space Complexity:** O(min(m, n))
73+
- Hash table stores at most min(m, n) characters
74+
- m is the size of the character set (ASCII: 128, Unicode: much larger)
75+
- n is the length of the string
76+
77+
## Key Insights
78+
79+
1. **Sliding Window Pattern:** This is a classic sliding window problem where we maintain a window of unique characters.
80+
81+
2. **Two Pointer Technique:** Using two pointers allows us to efficiently expand and shrink the window without recalculating from scratch.
82+
83+
3. **Hash Table for Tracking:** A hash table provides O(1) lookup to check if a character is already in the current window.
84+
85+
4. **Optimal Window Management:** When we encounter a duplicate, we shrink the window from the left until the duplicate is removed.
86+
87+
5. **Character Frequency vs. Presence:** We only need to track character presence (not frequency) since we want unique characters.
88+
89+
6. **Maximum Tracking:** We need to continuously update the maximum length as we process the string.
90+
91+
## Mistakes Made
92+
93+
1. **Inefficient Window Shrinking:** The current implementation removes characters one by one, which could be optimized.
94+
95+
2. **Character Tracking:** Using a simple dictionary instead of a set might be more appropriate for this use case.
96+
97+
3. **Edge Case Handling:** Need to ensure proper handling of empty strings and single characters.
98+
99+
## Related Problems
100+
101+
- **Longest Substring with At Most Two Distinct Characters** (Problem 159): Similar sliding window with character count limit
102+
- **Longest Substring with At Most K Distinct Characters** (Problem 340): Generalization of the above
103+
- **Minimum Window Substring** (Problem 76): Finding minimum window containing all characters from another string
104+
- **Substring with Concatenation of All Words** (Problem 30): More complex sliding window with word matching
105+
106+
## Alternative Approaches
107+
108+
1. **Brute Force:** Check all possible substrings - O(n³) time complexity
109+
2. **Optimized Brute Force:** Use hash set for each substring - O(n²) time complexity
110+
3. **Character Position Tracking:** Store last position of each character for O(1) window shrinking
111+
112+
## Common Pitfalls
113+
114+
1. **Confusing Substring vs Subsequence:** The problem asks for substring (consecutive characters), not subsequence.
115+
2. **Inefficient Duplicate Removal:** Removing characters one by one can be optimized.
116+
3. **Missing Edge Cases:** Empty string, single character, all same characters.
117+
4. **Character Set Size:** Consider the size of the character set for space complexity.
118+
119+
---
120+
121+
[![Back to Index](../../README.md#-problem-index)](../../README.md#-problem-index) | [![View Solution](../exercises/3.longest-substring-without-repeating-characters.py)](../exercises/3.longest-substring-without-repeating-characters.py)
122+
123+
*Note: This is a fundamental sliding window problem that introduces the concept of maintaining a dynamic window of unique elements.*

0 commit comments

Comments
 (0)