Skip to content

Commit abafcd8

Browse files
author
Wasim
committed
docs: add incredibly detailed deep dives for Sliding Window and Two Pointers
1 parent fc9c357 commit abafcd8

2 files changed

Lines changed: 130 additions & 0 deletions

File tree

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Understanding the Sliding Window Concept
2+
3+
Think of a Sliding Window like looking through a camera's zoom lens as you pan across a landscape. The full landscape is your data (a long list of numbers or characters), but at any single moment, you can only see a small portion—this portion is your "Window."
4+
5+
Instead of starting a new search from scratch every single time you move, you use the information already inside the window and just update what enters and what leaves. This saves huge amounts of time.
6+
7+
There are two primary types:
8+
1. **Fixed-Size Window** (The size is always constant).
9+
2. **Variable-Size Window** (The size grows or shrinks based on a condition).
10+
11+
## Type 1: Fixed-Size Sliding Window
12+
In this type, the window size (let's call it k) is fixed from the start. You might need to find the maximum sum of any k consecutive numbers, or the average of k elements. We slide the window one step at a time, keeping its size constant.
13+
14+
### The Process Step-by-Step
15+
**Goal:** Slide a window of exactly 3 elements across the data [A, B, C, D, E, F].
16+
17+
```plaintext
18+
Data: A B C D E F
19+
-----------------------
20+
Step 1: [A B C] (Initial window, calculate sum/average)
21+
Step 2: [B C D] (Slide right by 1: Drop A, Add D)
22+
Step 3: [C D E] (Slide right by 1: Drop B, Add E)
23+
Step 4: [D E F] (Slide right by 1: Drop C, Add F - End)
24+
```
25+
26+
## Type 2: Variable-Size Sliding Window
27+
A variable window does not have a fixed size. Instead, it expands or contracts based on a defined constraint. We maintain two pointers: a 'Right' pointer (the window's leading edge) and a 'Left' pointer (the window's trailing edge).
28+
29+
- **Expand**: We move the Right pointer to include new elements as long as the constraint is satisfied.
30+
- **Shrink**: If the constraint is violated, we move the Left pointer to remove elements from the window until the constraint is met again.
31+
32+
### The Process Step-by-Step
33+
**Goal:** Find segments where the sum of numbers is strictly less than 5 in the data [1, 2, 1, 3, 1, 4].
34+
35+
```plaintext
36+
Data: 1 2 1 3 1 4
37+
-----------------------
38+
Step 1: [1] (Sum = 1. Valid < 5, EXPAND right)
39+
Step 2: [1 2] (Sum = 3. Valid < 5, EXPAND right)
40+
Step 3: [1 2 1] (Sum = 4. Valid < 5, EXPAND right)
41+
Step 4: [1 2 1 3] (Sum = 7. INVALID! > 5, must SHRINK left)
42+
Step 5: 1 [2 1 3] (Sum = 6. INVALID! > 5, must SHRINK left)
43+
Step 6: 1 2 [1 3] (Sum = 4. Valid < 5, EXPAND right)
44+
Step 7: 1 2 [1 3 1] (Sum = 5. INVALID! Not < 5, SHRINK left)
45+
Step 8: 1 2 1 [3 1] (Sum = 4. Valid < 5, EXPAND right)
46+
Step 9: 1 2 1 [3 1 4] (Sum = 8. INVALID! > 5, SHRINK left)
47+
Step 10: 1 2 1 3 [1 4] (Sum = 5. INVALID! Not < 5, SHRINK left)
48+
Step 11: 1 2 1 3 1 [4] (Sum = 4. Valid < 5. Reached End)
49+
```
50+
51+
### Comparison Summary
52+
| Feature | Fixed-Size Window | Variable-Size Window |
53+
|---------|-------------------|----------------------|
54+
| **Size (k)** | Constant (Set at the beginning) | Dynamic (Grows or shrinks) |
55+
| **Pointers** | One pointer (usually tracking the window's start) | Two pointers (one Left, one Right) |
56+
| **Primary Action** | The window slides (shifted by one). | The window expands (R++) or shrinks (L++). |
57+
| **Used For...** | Analyzing a set amount of consecutive data. | Finding the best segment that meets a dynamic rule. |
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Understanding the Two Pointers Concept
2+
3+
Think of the Two Pointers technique like two people searching for a specific book on a long bookshelf. Instead of one person starting at the left and checking every single combination of books (which takes forever), one person starts at the far left, and the other starts at the far right. They look at the books they are holding, communicate, and take steps toward each other until they find exactly what they are looking for.
4+
5+
Instead of an O(N^2) double-loop comparing every single pair, we use two pointers to scan the array simultaneously, completing the search in just O(N) time.
6+
7+
There are two primary types:
8+
1. **Opposite Ends (Collision)** (Pointers start at opposite ends and move toward the center).
9+
2. **Same Direction (Trailing)** (Pointers start at the same end but move at different speeds or intervals).
10+
11+
## Type 1: Opposite Ends (Collision)
12+
In this type, the array must usually be **sorted**. We place a `Left` pointer at index 0 and a `Right` pointer at the last index. Because the array is sorted, we know exactly which pointer to move based on our current calculation.
13+
14+
- If the current sum is **too small**, we need a bigger number, so we move the `Left` pointer to the right.
15+
- If the current sum is **too big**, we need a smaller number, so we move the `Right` pointer to the left.
16+
17+
### The Process Step-by-Step
18+
**Goal:** Find a pair of numbers that add up to the Target Sum of `8` in the sorted data: `[1, 2, 3, 4, 6]`.
19+
20+
```plaintext
21+
Data: 1 2 3 4 6
22+
^ ^
23+
Left Right
24+
---------------------------------
25+
Step 1: [1] 2 3 4 [6] (1+6 = 7. 7 < 8. Too small! Move Left ->)
26+
Step 2: 1 [2] 3 4 [6] (2+6 = 8. TARGET FOUND! Stop.)
27+
```
28+
29+
Let's try a slightly longer one with a Target Sum of `10` in `[2, 3, 5, 8, 9, 11]`.
30+
31+
```plaintext
32+
Data: 2 3 5 8 9 11
33+
----------------------------------
34+
Step 1: [2] 3 5 8 9 [11] (2+11 = 13. 13 > 10. Too big! Move <- Right)
35+
Step 2: [2] 3 5 8 [9] 11 (2+9 = 11. 11 > 10. Too big! Move <- Right)
36+
Step 3: [2] 3 5 [8] 9 11 (2+8 = 10. TARGET FOUND! Stop.)
37+
```
38+
39+
## Type 2: Same Direction (Trailing/Slow & Fast)
40+
Here, both pointers start at the beginning (index 0). One pointer is the "explorer" (Fast), and the other is the "marker" (Slow). This is extremely common when you need to process an array in-place, like removing duplicates.
41+
42+
- **Fast Pointer**: Scans the array looking for new/unique elements.
43+
- **Slow Pointer**: Keeps track of where the next unique element should be placed.
44+
45+
### The Process Step-by-Step
46+
**Goal:** Remove duplicates from the sorted array `[1, 1, 2, 3, 3]` in-place.
47+
48+
```plaintext
49+
Data: 1 1 2 3 3
50+
-------------------------
51+
Step 1: [1] [1] 2 3 3 (Slow=0, Fast=1. Values match! Fast moves right.)
52+
^S ^F
53+
54+
Step 2: [1] 1 [2] 3 3 (Fast found a '2'. It's unique!)
55+
^S ^F (Action: Move Slow right, copy Fast's value to Slow)
56+
57+
Step 3: 1 [2] 2 [3] 3 (Array is now [1, 2, 2, 3, 3])
58+
^S ^F (Fast found a '3'. It's unique!)
59+
(Action: Move Slow right, copy Fast's value to Slow)
60+
61+
Step 4: 1 2 [3] 3 [3] (Array is now [1, 2, 3, 3, 3])
62+
^S ^F (Values match. Fast moves right, hits end.)
63+
64+
Result: The unique elements are everything from index 0 up to the Slow pointer: [1, 2, 3].
65+
```
66+
67+
### Comparison Summary
68+
| Feature | Opposite Ends (Collision) | Same Direction (Trailing) |
69+
|---------|---------------------------|---------------------------|
70+
| **Setup** | `Left` at start, `Right` at end. | `Slow` at start, `Fast` at start. |
71+
| **Requirement** | Array MUST usually be sorted. | Array doesn't always need to be sorted (depends on problem). |
72+
| **Primary Action** | Pointers step toward each other. | Fast pointer pulls ahead of the slow pointer. |
73+
| **Used For...** | Target sums, valid palindromes, reversing strings. | Removing duplicates in-place, filtering elements. |

0 commit comments

Comments
 (0)