diff --git a/BLIND75-GUIDE.md b/BLIND75-GUIDE.md
new file mode 100644
index 0000000..a0e3320
--- /dev/null
+++ b/BLIND75-GUIDE.md
@@ -0,0 +1,519 @@
+# Complete Blind 75 Problem-Solving Guide
+
+## π― What is Blind 75?
+
+Blind 75 is a curated list of 75 LeetCode problems that cover the most important patterns and concepts for technical interviews. Master these, and you'll be well-prepared for FAANG interviews.
+
+## π How to Use This Guide
+
+### Study Plan (8 Weeks)
+
+```mermaid
+graph LR
+ W1[Week 1:
Arrays & Hashing] --> W2[Week 2:
Two Pointers]
+ W2 --> W3[Week 3:
Sliding Window
& Stacks]
+ W3 --> W4[Week 4:
Binary Search
& Linked Lists]
+ W4 --> W5[Week 5:
Trees & Tries]
+ W5 --> W6[Week 6:
Heaps & Backtracking]
+ W6 --> W7[Week 7:
Graphs & DP]
+ W7 --> W8[Week 8:
Review & Practice]
+
+ style W1 fill:#FFE4B5
+ style W2 fill:#E0FFE0
+ style W3 fill:#E0E0FF
+ style W4 fill:#FFE0F0
+ style W5 fill:#E0F5FF
+ style W6 fill:#F5E0FF
+ style W7 fill:#FFE0E0
+ style W8 fill:#90EE90
+```
+
+## π₯ Problem-Solving Framework
+
+### The 5-Step Method
+
+```mermaid
+graph TD
+ Step1["1οΈβ£ UNDERSTAND
Read & clarify problem
Identify inputs/outputs
Ask questions"] --> Step2
+
+ Step2["2οΈβ£ EXAMPLES
Walk through examples
Find edge cases
Test your understanding"] --> Step3
+
+ Step3["3οΈβ£ APPROACH
Identify pattern
Choose data structure
Think of brute force first"] --> Step4
+
+ Step4["4οΈβ£ CODE
Start with pseudocode
Write clean code
Use good variable names"] --> Step5
+
+ Step5["5οΈβ£ TEST & OPTIMIZE
Test with examples
Check edge cases
Analyze complexity"]
+
+ style Step1 fill:#FFD700
+ style Step2 fill:#FFB6C1
+ style Step3 fill:#87CEEB
+ style Step4 fill:#90EE90
+ style Step5 fill:#DDA0DD
+```
+
+## π¨ Pattern Recognition Guide
+
+### How to Identify Which Pattern to Use
+
+```mermaid
+graph TD
+ Start[Read Problem] --> Q1{Input Type?}
+
+ Q1 -->|Array/String| Q2{Looking for?}
+ Q1 -->|Tree| TreePattern["DFS/BFS Pattern
See: Tree section"]
+ Q1 -->|Graph| GraphPattern["Graph Traversal
See: Graph section"]
+ Q1 -->|Numbers| Q3{What operation?}
+
+ Q2 -->|Pairs with target| Sorted{Array sorted?}
+ Sorted -->|Yes| TwoPtr["β Two Pointers
Two Sum II, 3Sum"]
+ Sorted -->|No| HashMap["β Hash Map
Two Sum"]
+
+ Q2 -->|Subarray/Substring| Window["β Sliding Window
Longest Substring,
Max Subarray"]
+
+ Q2 -->|All combinations| Backtrack["β Backtracking
Subsets, Permutations"]
+
+ Q3 -->|Optimization| DP["β Dynamic Programming
Climbing Stairs,
House Robber"]
+
+ Q3 -->|Find in range| BS["β Binary Search
Search in Rotated Array"]
+
+ style TwoPtr fill:#90EE90
+ style HashMap fill:#FFD700
+ style Window fill:#87CEEB
+ style Backtrack fill:#FFB6C1
+ style DP fill:#DDA0DD
+ style BS fill:#F0E68C
+```
+
+## π Pattern Deep Dives
+
+### Pattern 1: Two Pointers
+
+**When to Use:**
+- Array is sorted or can be sorted
+- Looking for pairs, triplets, or specific subarrays
+- Need O(1) space solution
+
+**Common Problems:**
+1. **Two Sum II** (Easy) - Sorted array, find pair
+2. **3Sum** (Medium) - Find triplets that sum to zero
+3. **Container With Most Water** (Medium) - Find max area
+4. **Valid Palindrome** (Easy) - Check palindrome
+
+**Template:**
+```python
+def two_pointers(arr):
+ left, right = 0, len(arr) - 1
+
+ while left < right:
+ # Calculate something with arr[left] and arr[right]
+ if condition_met:
+ return result
+ elif need_smaller_sum:
+ right -= 1 # Move right pointer left
+ else:
+ left += 1 # Move left pointer right
+
+ return default_result
+```
+
+**Visual Example - Two Sum II:**
+```
+Array: [2, 7, 11, 15], Target: 9
+
+Step 1: left=0, right=3
+ [2, 7, 11, 15]
+ β β
+ 2 + 15 = 17 > 9, move right left
+
+Step 2: left=0, right=2
+ [2, 7, 11, 15]
+ β β
+ 2 + 11 = 13 > 9, move right left
+
+Step 3: left=0, right=1
+ [2, 7, 11, 15]
+ β β
+ 2 + 7 = 9 β Found!
+```
+
+### Pattern 2: Sliding Window
+
+**When to Use:**
+- Need to find contiguous subarray/substring
+- Keywords: "longest", "shortest", "maximum", "minimum"
+- Want to optimize from O(nΒ²) to O(n)
+
+**Common Problems:**
+1. **Longest Substring Without Repeating Characters** (Medium)
+2. **Minimum Window Substring** (Hard)
+3. **Best Time to Buy and Sell Stock** (Easy)
+
+**Template:**
+```python
+def sliding_window(arr):
+ left = 0
+ window_data = {} # Track window state
+ result = 0
+
+ for right in range(len(arr)):
+ # Expand window: add arr[right]
+ window_data[arr[right]] = window_data.get(arr[right], 0) + 1
+
+ # Shrink window while invalid
+ while not is_valid(window_data):
+ window_data[arr[left]] -= 1
+ left += 1
+
+ # Update result
+ result = max(result, right - left + 1)
+
+ return result
+```
+
+**Visual Example - Longest Substring:**
+```
+String: "abcabcbb"
+
+Window: [a] - unique: 1
+Window: [ab] - unique: 2
+Window: [abc] - unique: 3 β best so far
+Window: [abca] - 'a' repeats! Shrink
+Window: [bca] - unique: 3
+Window: [cab] - unique: 3
+...continues
+```
+
+### Pattern 3: Fast & Slow Pointers
+
+**When to Use:**
+- Linked list problems
+- Detect cycles
+- Find middle element
+- Find kth from end
+
+**Common Problems:**
+1. **Linked List Cycle** (Easy)
+2. **Middle of Linked List** (Easy)
+3. **Happy Number** (Easy)
+
+**Template:**
+```python
+def fast_slow(head):
+ slow = fast = head
+
+ while fast and fast.next:
+ slow = slow.next # Move 1 step
+ fast = fast.next.next # Move 2 steps
+
+ if slow == fast:
+ return True # Cycle detected
+
+ return False # No cycle
+```
+
+### Pattern 4: Binary Search
+
+**When to Use:**
+- Array is sorted or rotated sorted
+- Need O(log n) solution
+- Search for element or boundary
+
+**Common Problems:**
+1. **Binary Search** (Easy)
+2. **Search in Rotated Sorted Array** (Medium)
+3. **Find Minimum in Rotated Sorted Array** (Medium)
+
+**Template:**
+```python
+def binary_search(arr, target):
+ left, right = 0, len(arr) - 1
+
+ while left <= right:
+ mid = left + (right - left) // 2
+
+ if arr[mid] == target:
+ return mid
+ elif arr[mid] < target:
+ left = mid + 1
+ else:
+ right = mid - 1
+
+ return -1
+```
+
+### Pattern 5: Backtracking
+
+**When to Use:**
+- Need to find ALL solutions
+- Generate combinations, permutations, subsets
+- Keywords: "find all", "generate all"
+
+**Common Problems:**
+1. **Subsets** (Medium)
+2. **Permutations** (Medium)
+3. **Combination Sum** (Medium)
+
+**Template:**
+```python
+def backtrack(arr):
+ result = []
+
+ def dfs(path, start):
+ # Base case - add current path to result
+ result.append(path[:])
+
+ # Try all possibilities
+ for i in range(start, len(arr)):
+ # Choose
+ path.append(arr[i])
+ # Explore
+ dfs(path, i + 1)
+ # Unchoose (backtrack)
+ path.pop()
+
+ dfs([], 0)
+ return result
+```
+
+### Pattern 6: Dynamic Programming
+
+**When to Use:**
+- Optimization problems (min/max/longest/shortest)
+- Count number of ways
+- Has overlapping subproblems
+- Has optimal substructure
+
+**Common Problems:**
+1. **Climbing Stairs** (Easy)
+2. **House Robber** (Medium)
+3. **Longest Increasing Subsequence** (Medium)
+4. **Coin Change** (Medium)
+
+**5-Step DP Framework:**
+```
+1. Define the state
+ - What does dp[i] represent?
+
+2. Find the recurrence relation
+ - How does dp[i] relate to previous states?
+
+3. Initialize base cases
+ - What are dp[0], dp[1]?
+
+4. Determine iteration order
+ - Forward or backward?
+
+5. Return the answer
+ - Usually dp[n] or max(dp)
+```
+
+**Template:**
+```python
+def dp_bottom_up(n):
+ # Step 1 & 3: Initialize
+ dp = [0] * (n + 1)
+ dp[0] = base_case_0
+ dp[1] = base_case_1
+
+ # Step 4: Fill table
+ for i in range(2, n + 1):
+ # Step 2: Recurrence relation
+ dp[i] = dp[i-1] + dp[i-2] # Example: Fibonacci
+
+ # Step 5: Return answer
+ return dp[n]
+```
+
+## π― Complete Blind 75 Checklist
+
+### Arrays & Hashing (9 problems)
+
+| Problem | Difficulty | Pattern | Key Concept |
+|---------|-----------|---------|-------------|
+| Two Sum | Easy | Hash Map | Store complement |
+| Best Time to Buy and Sell Stock | Easy | One Pass | Track min, max profit |
+| Contains Duplicate | Easy | Hash Set | Check existence |
+| Product of Array Except Self | Medium | Prefix/Suffix | Two passes |
+| Maximum Subarray | Easy | Kadane's Algorithm | Dynamic Programming |
+| Maximum Product Subarray | Medium | Track min/max | Handle negatives |
+| Find Minimum in Rotated Sorted Array | Medium | Binary Search | Find pivot |
+| Search in Rotated Sorted Array | Medium | Modified Binary Search | Check which half sorted |
+| 3Sum | Medium | Two Pointers | Sort + avoid duplicates |
+
+**Pro Tip:** For array problems, always consider:
+1. Can I use hash map for O(1) lookup?
+2. Is array sorted? Can I use two pointers or binary search?
+3. Can I solve in one pass?
+4. What if I use prefix/suffix arrays?
+
+### Linked Lists (6 problems)
+
+| Problem | Difficulty | Pattern | Key Concept |
+|---------|-----------|---------|-------------|
+| Reverse Linked List | Easy | Iterative/Recursive | Three pointers |
+| Detect Cycle | Easy | Fast & Slow | Floyd's algorithm |
+| Merge Two Sorted Lists | Easy | Two Pointers | Compare & merge |
+| Merge K Sorted Lists | Hard | Heap/Divide & Conquer | Priority queue |
+| Remove Nth Node From End | Medium | Two Pass/One Pass | Gap of n |
+| Reorder List | Medium | Find Middle + Reverse | Combine techniques |
+
+**Pro Tip:** For linked lists:
+1. Draw it out! Visual helps a lot
+2. Consider dummy node for edge cases
+3. Fast & slow pointers for middle/cycle
+4. Remember to handle NULL cases
+
+### Trees (11 problems)
+
+| Problem | Difficulty | Pattern | Key Concept |
+|---------|-----------|---------|-------------|
+| Maximum Depth | Easy | DFS/BFS | Recursion |
+| Same Tree | Easy | DFS | Compare both |
+| Invert Binary Tree | Easy | DFS | Swap children |
+| Binary Tree Level Order | Medium | BFS | Use queue |
+| Validate BST | Medium | DFS | Track min/max |
+| Kth Smallest in BST | Medium | Inorder Traversal | Sorted order |
+| Lowest Common Ancestor | Medium | DFS | Path finding |
+| Construct Tree from Preorder & Inorder | Medium | Recursion | Find root pattern |
+| Binary Tree Maximum Path Sum | Hard | DFS | Return vs update |
+| Serialize/Deserialize | Hard | BFS/DFS | String encoding |
+| Subtree of Another Tree | Easy | DFS | Match trees |
+
+**Pro Tip:** For trees:
+1. DFS = recursion or stack
+2. BFS = queue (level order)
+3. For BST, use inorder for sorted
+4. Draw small examples first
+
+### Dynamic Programming (12 problems)
+
+| Problem | Difficulty | Pattern | Key Concept |
+|---------|-----------|---------|-------------|
+| Climbing Stairs | Easy | 1D DP | Fibonacci |
+| Coin Change | Medium | 1D DP | Min coins |
+| Longest Increasing Subsequence | Medium | 1D DP | Track best ending here |
+| Longest Common Subsequence | Medium | 2D DP | Match characters |
+| Word Break | Medium | 1D DP | Dictionary lookup |
+| Combination Sum IV | Medium | 1D DP | Order matters |
+| House Robber | Medium | 1D DP | Max with constraint |
+| House Robber II | Medium | 1D DP | Circular array |
+| Decode Ways | Medium | 1D DP | Count combinations |
+| Unique Paths | Medium | 2D DP | Grid paths |
+| Jump Game | Medium | Greedy/DP | Reachability |
+
+**Pro Tip:** For DP:
+1. Start with brute force recursion
+2. Add memoization (top-down)
+3. Convert to tabulation (bottom-up)
+4. Optimize space if possible
+
+## π Interview Day Strategy
+
+### Before Coding
+
+```mermaid
+graph TD
+ Start[Problem Given] --> Clarify["Clarify Requirements
β’ Input constraints?
β’ Edge cases?
β’ Output format?"]
+
+ Clarify --> Examples["Work Through Examples
β’ Simple case
β’ Edge case
β’ Large case"]
+
+ Examples --> Pattern["Identify Pattern
β’ What category?
β’ Similar problems?
β’ Time constraints?"]
+
+ Pattern --> Discuss["Discuss Approach
β’ Explain brute force
β’ Explain optimization
β’ Get approval"]
+
+ Discuss --> Code["Start Coding
β’ Write clean code
β’ Explain as you go
β’ Use good names"]
+
+ style Start fill:#FFD700
+ style Clarify fill:#FFB6C1
+ style Examples fill:#87CEEB
+ style Pattern fill:#90EE90
+ style Discuss fill:#DDA0DD
+ style Code fill:#F0E68C
+```
+
+### Time Management (45 minutes)
+
+- **5 min:** Understand problem & clarify
+- **5 min:** Work through examples
+- **5 min:** Identify pattern & discuss approach
+- **20 min:** Code the solution
+- **5 min:** Test with examples
+- **5 min:** Discuss optimizations & edge cases
+
+### Communication Tips
+
+**DO:**
+- Think out loud
+- Explain your approach before coding
+- Ask clarifying questions
+- Test your code with examples
+- Discuss trade-offs
+
+**DON'T:**
+- Jump straight to coding
+- Stay silent
+- Ignore edge cases
+- Give up easily
+- Argue with interviewer
+
+## π§ Common Pitfalls & How to Avoid
+
+### Pitfall 1: Not Understanding the Problem
+**Solution:** Rephrase problem in your own words, work through examples
+
+### Pitfall 2: Jumping to Code Too Fast
+**Solution:** Discuss approach first, get approval before coding
+
+### Pitfall 3: Ignoring Edge Cases
+**Solution:** Always test: empty input, single element, all same values
+
+### Pitfall 4: Not Testing Code
+**Solution:** Walk through your code with examples, even simple ones
+
+### Pitfall 5: Poor Time Management
+**Solution:** If stuck >5 min, ask for hint or try simpler approach
+
+## π Additional Resources
+
+### Practice Schedule
+
+**Week 1-2:** Easy problems only
+**Week 3-4:** Mix of easy and medium
+**Week 5-6:** Medium problems focus
+**Week 7-8:** Mix of medium and hard + review
+
+### Daily Routine
+
+1. **Morning (1 hour):**
+ - Review patterns and templates
+ - Solve 1-2 easy problems
+
+2. **Evening (1-2 hours):**
+ - Solve 1-2 medium/hard problems
+ - Review solutions, note patterns
+
+3. **Weekend:**
+ - Mock interviews
+ - Review weak areas
+ - Solve challenging problems
+
+## π Mastery Checklist
+
+- [ ] Can identify pattern within 2 minutes
+- [ ] Know all templates by heart
+- [ ] Can code optimal solution in 15-20 minutes
+- [ ] Can explain time & space complexity
+- [ ] Can handle follow-up questions
+- [ ] Comfortable with all data structures
+- [ ] Can optimize brute force solutions
+- [ ] Know common edge cases for each pattern
+
+## π‘ Final Tips
+
+1. **Consistency > Intensity:** 2 hours daily beats 14 hours on weekend
+2. **Quality > Quantity:** Understand 1 problem deeply beats solving 5 superficially
+3. **Patterns > Problems:** Learn patterns, problems become variations
+4. **Mock Interviews:** Practice under pressure, get feedback
+5. **Review Mistakes:** Your best learning comes from wrong attempts
+
+Remember: Everyone struggles at first. Keep practicing, and patterns will become second nature!
diff --git a/README.md b/README.md
index 8ee69fc..6ceb87b 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,82 @@
# Data Structures and Algorithms Cheatsheet
-A comprehensive guide to common data structures and algorithms with implementation examples in Python and JavaScript.
+A comprehensive, visual guide to common data structures and algorithms with implementation examples in Python and JavaScript. Each topic includes detailed mermaid diagrams for better understanding.
+
+## π― Quick Navigation
+
+```mermaid
+graph TB
+ Start[DSA Cheatsheet] --> Foundations
+ Start --> DS[Data Structures]
+ Start --> Algo[Algorithms]
+ Start --> Patterns[Patterns]
+ Start --> Problems[Blind 75]
+
+ Foundations[π Foundations] --> BigO[Big O Notation]
+
+ DS --> Linear[Linear Structures]
+ DS --> Hierarchical[Hierarchical Structures]
+ DS --> Hash[Hash-Based Structures]
+
+ Linear --> Arrays[Arrays/Lists]
+ Linear --> LinkedLists[Linked Lists]
+ Linear --> Stacks[Stacks]
+ Linear --> Queues[Queues]
+
+ Hierarchical --> Trees[Trees]
+ Hierarchical --> Heaps[Heaps]
+ Hierarchical --> Tries[Tries]
+ Hierarchical --> Graphs[Graphs]
+
+ Hash --> HashTables[Hash Tables/Maps]
+
+ Algo --> Sorting[Sorting]
+ Algo --> Searching[Searching]
+ Algo --> DP[Dynamic Programming]
+ Algo --> Greedy[Greedy]
+ Algo --> Backtrack[Backtracking]
+ Algo --> GraphAlgo[Graph Algorithms]
+
+ Patterns --> TwoPointers[Two Pointers]
+ Patterns --> SlidingWindow[Sliding Window]
+ Patterns --> FastSlow[Fast & Slow Pointers]
+ Patterns --> BinarySearch[Binary Search]
+
+ Problems --> Array75[Array Problems]
+ Problems --> Tree75[Tree Problems]
+ Problems --> Graph75[Graph Problems]
+
+ style Start fill:#FFD700
+ style Foundations fill:#87CEEB
+ style DS fill:#90EE90
+ style Algo fill:#FFB6C1
+ style Patterns fill:#DDA0DD
+ style Problems fill:#F0E68C
+```
+
+## π Learning Path
+
+```mermaid
+graph LR
+ Step1[1. Big O Notation] --> Step2[2. Basic DS:
Arrays, Linked Lists]
+ Step2 --> Step3[3. Stacks & Queues]
+ Step3 --> Step4[4. Recursion &
Basic Sorting]
+ Step4 --> Step5[5. Trees & BST]
+ Step5 --> Step6[6. Hash Tables]
+ Step6 --> Step7[7. Graphs & Traversals]
+ Step7 --> Step8[8. Advanced Algorithms:
DP, Greedy, Backtracking]
+ Step8 --> Step9[9. Practice:
Blind 75 Problems]
+
+ style Step1 fill:#FFE4B5
+ style Step2 fill:#E0FFE0
+ style Step3 fill:#E0E0FF
+ style Step4 fill:#FFE0F0
+ style Step5 fill:#E0F5FF
+ style Step6 fill:#F5E0FF
+ style Step7 fill:#FFE0E0
+ style Step8 fill:#E0FFE0
+ style Step9 fill:#90EE90
+```
## Table of Contents
@@ -378,16 +454,88 @@ Each solution file will contain:
6. Time and space complexity analysis
7. Edge cases and optimizations
+## π§ Problem-Solving Decision Tree
+
+When faced with a coding problem, use this flowchart to determine the best approach:
+
+```mermaid
+graph TD
+ Start[New Problem] --> Q1{Type of problem?}
+
+ Q1 -->|Array/String| Q2{Need to find pairs
or subsequences?}
+ Q1 -->|Tree/Graph| Q3{Need traversal?}
+ Q1 -->|Optimization| Q4{Overlapping
subproblems?}
+ Q1 -->|Collection| Q5{Need fast
lookup/insertion?}
+
+ Q2 -->|Pairs in sorted array| TwoPtr[Two Pointers Pattern]
+ Q2 -->|Subarray with condition| SlidingWin[Sliding Window Pattern]
+ Q2 -->|Multiple solutions| Backtrack[Backtracking]
+
+ Q3 -->|Level by level| BFS[BFS - Use Queue]
+ Q3 -->|Deep exploration| DFS[DFS - Use Stack/Recursion]
+ Q3 -->|Shortest path| ShortestPath[Dijkstra/BFS]
+ Q3 -->|Detect cycle| CycleDetect[Union-Find or DFS]
+
+ Q4 -->|Yes, can cache| DP[Dynamic Programming]
+ Q4 -->|No, greedy choice| Greedy[Greedy Algorithm]
+ Q4 -->|Generate all| BacktrackOpt[Backtracking]
+
+ Q5 -->|Key-value pairs| HashMap[Hash Map/Table]
+ Q5 -->|Ordered data| BST[Binary Search Tree]
+ Q5 -->|Priority-based| Heap[Min/Max Heap]
+ Q5 -->|Range queries| SegTree[Segment Tree]
+
+ style TwoPtr fill:#87CEEB
+ style SlidingWin fill:#90EE90
+ style BFS fill:#FFB6C1
+ style DFS fill:#DDA0DD
+ style DP fill:#FFD700
+ style Greedy fill:#F0E68C
+ style HashMap fill:#FFE4B5
+ style Heap fill:#E0FFE0
+```
+
+## π Complexity Cheat Sheet
+
+Quick reference for common operations:
+
+```mermaid
+graph TD
+ subgraph "Data Structure Time Complexities"
+ A[Array] --> A1["Access: O(1)
Search: O(n)
Insert: O(n)
Delete: O(n)"]
+ B[Linked List] --> B1["Access: O(n)
Search: O(n)
Insert: O(1)
Delete: O(1)"]
+ C[Hash Table] --> C1["Access: N/A
Search: O(1)
Insert: O(1)
Delete: O(1)"]
+ D[Binary Search Tree] --> D1["Access: O(log n)
Search: O(log n)
Insert: O(log n)
Delete: O(log n)"]
+ end
+
+ subgraph "Algorithm Time Complexities"
+ E[Binary Search] --> E1["O(log n)
Requires sorted array"]
+ F[Merge Sort] --> F1["O(n log n)
Stable, uses O(n) space"]
+ G[Quick Sort] --> G1["O(n log n) avg
O(nΒ²) worst
In-place"]
+ H[BFS/DFS] --> H1["O(V + E)
V=vertices, E=edges"]
+ end
+
+ style A1 fill:#E0FFE0
+ style B1 fill:#FFE0E0
+ style C1 fill:#90EE90
+ style D1 fill:#E0F5FF
+ style E1 fill:#FFE4B5
+ style F1 fill:#E0E0FF
+ style G1 fill:#FFE0F0
+ style H1 fill:#F5E0FF
+```
+
## How to Use This Cheatsheet
Each topic includes:
-- Conceptual explanations
-- Visual representations
-- Implementation in Python and JavaScript
-- Common patterns and techniques
-- Problem identification tips
-- Time and space complexity analysis
-- Common pitfalls and how to avoid them
+- **Conceptual explanations** with real-world analogies
+- **Visual representations** using mermaid diagrams
+- **Implementation** in Python and JavaScript
+- **Common patterns** and techniques
+- **Problem identification** tips
+- **Time and space complexity** analysis
+- **Common pitfalls** and how to avoid them
+- **Step-by-step visualizations** for complex operations
## Contributing
diff --git a/algorithms/backtracking.md b/algorithms/backtracking.md
index 002aa7d..177a683 100644
--- a/algorithms/backtracking.md
+++ b/algorithms/backtracking.md
@@ -4,6 +4,7 @@ Backtracking is an algorithmic technique for solving problems recursively by try
## Table of Contents
- [Understanding Backtracking](#understanding-backtracking)
+- [How to Approach Backtracking Problems](#how-to-approach-backtracking-problems)
- [Backtracking Template](#backtracking-template)
- [Common Backtracking Problems](#common-backtracking-problems)
- [Optimization Techniques](#optimization-techniques)
@@ -61,6 +62,236 @@ Step 6: Try to place queen in fourth row
. . Q . (valid solution found)
```
+## How to Approach Backtracking Problems
+
+### Step 1: Identify if the Problem Requires Backtracking
+
+```mermaid
+graph TD
+ Start[Problem Analysis] --> Q1{Need to find ALL
solutions?}
+
+ Q1 -->|Yes| Q2{Generate combinations,
permutations, or subsets?}
+ Q1 -->|No, just one solution| Q3{Can use greedy
or DP?}
+
+ Q2 -->|Yes| Backtrack1[β Use Backtracking
Pattern: Enumeration]
+ Q2 -->|No| Q4{Placement problem
with constraints?}
+
+ Q3 -->|Yes| Other[Consider other approaches]
+ Q3 -->|No| Q4
+
+ Q4 -->|Yes| Backtrack2[β Use Backtracking
Pattern: Constraint Satisfaction]
+ Q4 -->|No| Q5{Path finding with
multiple routes?}
+
+ Q5 -->|Yes| Backtrack3[β Use Backtracking
Pattern: Path Exploration]
+ Q5 -->|No| Consider[Consider other algorithms]
+
+ style Backtrack1 fill:#90EE90
+ style Backtrack2 fill:#90EE90
+ style Backtrack3 fill:#90EE90
+ style Other fill:#FFB6C1
+ style Consider fill:#FFB6C1
+```
+
+### Step 2: Define Your Backtracking Components
+
+```mermaid
+graph TD
+ Setup[Setup Phase] --> Define1[1. Define State
What info do you need to track?]
+ Define1 --> Define2[2. Define Choices
What decisions can you make?]
+ Define2 --> Define3[3. Define Constraints
What makes a choice invalid?]
+ Define3 --> Define4[4. Define Goal
When is solution complete?]
+ Define4 --> Implement[Implementation Phase]
+
+ Implement --> Code1[Write base case]
+ Code1 --> Code2[Iterate through choices]
+ Code2 --> Code3[Check constraints]
+ Code3 --> Code4[Make choice - recurse - undo]
+
+ style Setup fill:#FFD700
+ style Implement fill:#87CEEB
+ style Code4 fill:#90EE90
+```
+
+### Step 3: The Backtracking Problem-Solving Framework
+
+#### Phase 1: Problem Analysis (Before Writing Code)
+
+```
+1. IDENTIFY THE PATTERN
+ β‘ Need to generate all combinations/permutations?
+ β‘ Need to explore all possible paths?
+ β‘ Need to satisfy constraints while building solution?
+ β‘ Keywords: "all possible", "find all", "generate all"
+
+2. DEFINE THE STATE
+ Question: What information do I need to track?
+ Examples:
+ - Current path/combination/permutation
+ - Current position in input
+ - Set of used elements
+ - Current state of the board/grid
+
+3. DEFINE THE CHOICES
+ Question: At each step, what decisions can I make?
+ Examples:
+ - Which element to add next?
+ - Which direction to move?
+ - Which position to place something?
+
+4. DEFINE THE CONSTRAINTS
+ Question: When is a choice invalid?
+ Examples:
+ - Element already used
+ - Position under attack (N-Queens)
+ - Sum exceeds target
+ - Out of bounds
+
+5. DEFINE THE GOAL
+ Question: When is my solution complete?
+ Examples:
+ - Used all elements
+ - Reached target sum
+ - Filled all positions
+ - Reached end of path
+```
+
+#### Phase 2: Implementation Strategy
+
+```mermaid
+graph LR
+ A[Start] --> B[Write Base Case
If goal reached:
save solution, return]
+ B --> C[Loop Through
Available Choices]
+ C --> D{Is choice
valid?}
+ D -->|No| C
+ D -->|Yes| E[Make Choice
Add to path/state]
+ E --> F[Recursive Call
with updated state]
+ F --> G[Backtrack
Undo choice,
remove from state]
+ G --> C
+
+ style A fill:#FFD700
+ style B fill:#90EE90
+ style E fill:#87CEEB
+ style F fill:#DDA0DD
+ style G fill:#FFA500
+```
+
+### Step 4: Common Backtracking Patterns
+
+#### Pattern 1: Combinations & Subsets
+
+```
+Use when: Selecting items from a collection
+Template approach:
+1. State: current combination, start index
+2. Choices: elements from start to end
+3. Constraint: avoid duplicates by using start index
+4. Goal: any point can be a valid subset
+```
+
+#### Pattern 2: Permutations
+
+```
+Use when: Arranging items in different orders
+Template approach:
+1. State: current permutation, used set
+2. Choices: any unused element
+3. Constraint: element not already in permutation
+4. Goal: permutation length equals input length
+```
+
+#### Pattern 3: Constraint Satisfaction (N-Queens, Sudoku)
+
+```
+Use when: Placing items with conflict constraints
+Template approach:
+1. State: current board configuration
+2. Choices: valid positions for next item
+3. Constraint: placement doesn't violate rules
+4. Goal: all positions filled validly
+```
+
+#### Pattern 4: Path Finding (Word Search, Maze)
+
+```
+Use when: Finding paths through grid/graph
+Template approach:
+1. State: current position, path taken
+2. Choices: adjacent unvisited cells
+3. Constraint: in bounds, not visited, matches criteria
+4. Goal: reached destination or found target
+```
+
+### Step 5: Optimization Checklist
+
+```
+Before submitting your solution, consider:
+
+β‘ Can I prune branches early?
+ - Check constraints BEFORE making recursive call
+ - Sort input to enable early termination
+
+β‘ Can I avoid duplicate work?
+ - Skip duplicate elements
+ - Use memoization if subproblems overlap
+
+β‘ Is my state representation efficient?
+ - Use bit manipulation for sets
+ - Use single array instead of copying
+
+β‘ Am I properly backtracking?
+ - Every modification must be undone
+ - Test with small examples to verify
+```
+
+### Example: Applying the Framework to Combination Sum
+
+```
+PROBLEM: Find all unique combinations that sum to target
+
+STEP 1: Identify Pattern
+β Need to find ALL combinations β Backtracking
+β Pattern: Combinations with repetition allowed
+
+STEP 2: Define Components
+- State: current combination, current sum, start index
+- Choices: candidates from start index onwards
+- Constraints: sum doesn't exceed target
+- Goal: sum equals target
+
+STEP 3: Implementation Plan
+1. Base case: if sum == target, add to results
+2. Pruning: if sum > target, return early
+3. Loop through candidates from start
+4. Add candidate β Recurse β Remove candidate
+
+STEP 4: Code Structure
+def backtrack(start, curr_sum, curr_comb):
+ # Base case - found solution
+ if curr_sum == target:
+ result.append(curr_comb[:])
+ return
+
+ # Pruning - exceeded target
+ if curr_sum > target:
+ return
+
+ # Try each choice
+ for i in range(start, len(candidates)):
+ curr_comb.append(candidates[i]) # Make choice
+ backtrack(i, curr_sum + candidates[i], curr_comb) # Recurse
+ curr_comb.pop() # Backtrack
+```
+
+### Decision Matrix: Backtracking vs. Other Approaches
+
+| Criteria | Use Backtracking | Consider Alternative |
+|----------|------------------|---------------------|
+| Output needed | ALL solutions | ONE optimal solution β DP/Greedy |
+| Problem type | Combinatorial | Optimization β DP |
+| Constraints | Complex rules | Simple conditions β Iteration |
+| Solution space | Explore all paths | Find shortest path β BFS |
+| Time limit | Reasonable input size | Very large input β Heuristics |
+
## Backtracking Template
Most backtracking algorithms follow a similar structure:
diff --git a/algorithms/dynamic-programming.md b/algorithms/dynamic-programming.md
index d7421dc..dc3e752 100644
--- a/algorithms/dynamic-programming.md
+++ b/algorithms/dynamic-programming.md
@@ -26,22 +26,92 @@ Dynamic Programming (DP) is a powerful technique used to solve complex problems
## Visual Representation
-Consider the Fibonacci sequence calculation:
+### Fibonacci Without DP vs With DP
+
+```mermaid
+graph TD
+ subgraph "Without DP - Exponential Time O(2^n)"
+ F5["fib(5)"] --> F4A["fib(4)"]
+ F5 --> F3A["fib(3)"]
+ F4A --> F3B["fib(3) β οΈ duplicate"]
+ F4A --> F2A["fib(2)"]
+ F3A --> F2B["fib(2) β οΈ duplicate"]
+ F3A --> F1A["fib(1)"]
+ F3B --> F2C["fib(2) β οΈ duplicate"]
+ F3B --> F1B["fib(1)"]
+ end
+
+ style F3B fill:#FFB6C6
+ style F2B fill:#FFB6C6
+ style F2C fill:#FFB6C6
+```
+
+```mermaid
+graph LR
+ subgraph "With DP - Linear Time O(n)"
+ Start[Calculate fib 5] --> Check1{fib 4 cached?}
+ Check1 -->|No| Calc4[Calculate fib 4]
+ Check1 -->|Yes| Use4[Use cached value]
+ Calc4 --> Cache4[Cache result]
+ Cache4 --> Check2{fib 3 cached?}
+ Check2 -->|No| Calc3[Calculate fib 3]
+ Check2 -->|Yes| Use3["Use cached β
No recomputation!"]
+ end
+
+ style Use3 fill:#90EE90
+ style Calc3 fill:#FFD700
+```
+
+### DP Approach Decision Tree
+
+```mermaid
+graph TD
+ Start[DP Problem] --> Q1{Can identify
subproblems?}
+
+ Q1 -->|Yes| Q2{Subproblems
overlap?}
+ Q1 -->|No| NotDP["Not a DP problem
Try greedy or divide-conquer"]
+
+ Q2 -->|Yes| Q3{Optimal
substructure?}
+ Q2 -->|No| NotDP2["Not a DP problem
No benefit from caching"]
+
+ Q3 -->|Yes| IsDP["β DP Problem!"]
+ Q3 -->|No| NotDP3["Not a DP problem"]
+
+ IsDP --> Q4{Choose approach?}
+ Q4 -->|Easier to think| TopDown["Top-Down (Memoization)
β’ Start from main problem
β’ Recursive
β’ Cache results
β’ More intuitive"]
+
+ Q4 -->|More efficient| BottomUp["Bottom-Up (Tabulation)
β’ Start from base cases
β’ Iterative
β’ Build table
β’ Better space optimization"]
+
+ style IsDP fill:#90EE90
+ style TopDown fill:#87CEEB
+ style BottomUp fill:#FFD700
```
- fib(5)
- / \
- fib(4) fib(3)
- / \ / \
- fib(3) fib(2) fib(2) fib(1)
- / \ / \ / \
- fib(2) fib(1) fib(1) fib(0) fib(1) fib(0)
- / \
- fib(1) fib(0)
+
+### Common DP Patterns Visual
+
+```mermaid
+graph TD
+ Patterns[DP Pattern Types] --> P1[Linear DP]
+ Patterns --> P2[Grid/2D DP]
+ Patterns --> P3[Subsequence DP]
+ Patterns --> P4[Interval DP]
+
+ P1 --> P1E["Examples:
β’ Fibonacci
β’ Climbing Stairs
β’ House Robber
1D array: dp[i]"]
+
+ P2 --> P2E["Examples:
β’ Unique Paths
β’ Min Path Sum
β’ Edit Distance
2D array: dp[i][j]"]
+
+ P3 --> P3E["Examples:
β’ LCS
β’ LIS
β’ Palindrome problems
Track subsequence state"]
+
+ P4 --> P4E["Examples:
β’ Matrix Chain Mult
β’ Burst Balloons
dp[i][j] for range [i,j]"]
+
+ style P1 fill:#90EE90
+ style P2 fill:#FFD700
+ style P3 fill:#87CEEB
+ style P4 fill:#FFB6C1
```
-Without DP, many subproblems (like fib(3), fib(2), etc.) are calculated multiple times.
-With DP, we calculate each subproblem only once and reuse the result.
+Consider the Fibonacci sequence calculation:
## Common Dynamic Programming Problems
@@ -409,4 +479,243 @@ Look for these clues in the problem statement:
2. The solution involves making choices at each step, and these choices affect future options.
3. The problem can be broken down into smaller, similar subproblems.
4. There are overlapping subproblems (the same subproblem is solved multiple times).
-5. Keywords like "count the number of ways," "find the minimum/maximum," or "is it possible to achieve."
\ No newline at end of file
+5. Keywords like "count the number of ways," "find the minimum/maximum," or "is it possible to achieve."
+
+## π‘ Advanced Tips and Tricks
+
+### DP Problem-Solving Framework
+
+```mermaid
+graph TD
+ Start[DP Problem] --> Step1["1. Define State
What represents a subproblem?"]
+ Step1 --> Step2["2. Find Recurrence
How do subproblems relate?"]
+ Step2 --> Step3["3. Base Cases
Simplest subproblems?"]
+ Step3 --> Step4["4. Choose Approach
Top-down or bottom-up?"]
+ Step4 --> Step5["5. Implement & Optimize
Space optimization possible?"]
+
+ Step5 --> Result["Solution Complete!"]
+
+ style Step1 fill:#FFE4B5
+ style Step2 fill:#FFD700
+ style Step3 fill:#FFA500
+ style Step4 fill:#87CEEB
+ style Step5 fill:#90EE90
+ style Result fill:#90EE90
+```
+
+### State Design Patterns
+
+```mermaid
+graph LR
+ subgraph "Common State Designs"
+ S1["dp[i]
Linear
Current position"]
+ S2["dp[i][j]
2D Grid
Two positions/dimensions"]
+ S3["dp[i][j][k]
3D State
Multiple constraints"]
+ S4["dp[i][state]
With Status
Position + condition"]
+ end
+
+ S1 --> E1["Examples:
Fibonacci, Stairs"]
+ S2 --> E2["Examples:
LCS, Edit Distance"]
+ S3 --> E3["Examples:
3D path problems"]
+ S4 --> E4["Examples:
Buy/Sell Stock with states"]
+
+ style S1 fill:#90EE90
+ style S2 fill:#FFD700
+ style S3 fill:#87CEEB
+ style S4 fill:#FFB6C1
+```
+
+### Pro Tips for Interviews
+
+**1. Start with Recursion, Add Memoization**
+```python
+# Step 1: Write recursive solution
+def solve_recursive(n):
+ if n <= 1:
+ return n
+ return solve_recursive(n-1) + solve_recursive(n-2)
+
+# Step 2: Add memoization (convert to DP)
+def solve_dp(n, memo={}):
+ if n in memo:
+ return memo[n]
+ if n <= 1:
+ return n
+ memo[n] = solve_dp(n-1, memo) + solve_dp(n-2, memo)
+ return memo[n]
+```
+
+**2. Identify the State Transition**
+```python
+# General pattern for 1D DP
+dp[i] = function(dp[i-1], dp[i-2], ..., dp[0])
+
+# Example: Climbing Stairs
+# Can reach step i from (i-1) or (i-2)
+dp[i] = dp[i-1] + dp[i-2]
+```
+
+**3. Space Optimization Technique**
+```python
+# Original: O(n) space
+dp = [0] * (n+1)
+for i in range(n+1):
+ dp[i] = calculate(dp)
+
+# Optimized: O(1) space (when only last few states matter)
+prev2, prev1 = 0, 1
+for i in range(2, n+1):
+ curr = prev1 + prev2
+ prev2, prev1 = prev1, curr
+```
+
+**4. Template for Top-Down DP**
+```python
+def dp_top_down(params, memo={}):
+ # Check memo
+ key = make_key(params)
+ if key in memo:
+ return memo[key]
+
+ # Base case
+ if is_base_case(params):
+ return base_value
+
+ # Recursive case
+ result = combine(
+ dp_top_down(subproblem1, memo),
+ dp_top_down(subproblem2, memo)
+ )
+
+ # Store and return
+ memo[key] = result
+ return result
+```
+
+**5. Template for Bottom-Up DP**
+```python
+def dp_bottom_up(n):
+ # Initialize DP table
+ dp = [0] * (n+1)
+
+ # Base cases
+ dp[0] = base_value_0
+ dp[1] = base_value_1
+
+ # Fill table
+ for i in range(2, n+1):
+ dp[i] = combine(dp[i-1], dp[i-2])
+
+ return dp[n]
+```
+
+### Common DP Optimizations
+
+```mermaid
+graph TD
+ Opt[Optimization Techniques] --> O1["Space Optimization"]
+ Opt --> O2["State Reduction"]
+ Opt --> O3["Early Termination"]
+
+ O1 --> O1D["2D β 1D array
Use only prev row/column
Rolling array technique"]
+ O2 --> O2D["Compress state
Use bitmask for sets
Reduce dimensions"]
+ O3 --> O3D["Prune impossible states
Track min/max bounds
Break when found"]
+
+ style O1 fill:#90EE90
+ style O2 fill:#FFD700
+ style O3 fill:#87CEEB
+```
+
+### Debugging DP Solutions
+
+```mermaid
+graph TD
+ Debug[DP Solution Wrong?] --> D1{Check base cases}
+ Debug --> D2{Verify recurrence}
+ Debug --> D3{Check iteration order}
+
+ D1 -->|Wrong| D1F["Fix base cases:
β’ dp[0], dp[1] correct?
β’ Empty input handled?"]
+
+ D2 -->|Wrong| D2F["Verify transition:
β’ All states considered?
β’ Correct combination?"]
+
+ D3 -->|Wrong| D3F["Fix order:
β’ Dependencies computed first?
β’ Inner/outer loops correct?"]
+
+ style D1F fill:#FFB6C6
+ style D2F fill:#FFB6C6
+ style D3F fill:#FFB6C6
+```
+
+### Interview Strategy
+
+**1. Recognize DP Signals:**
+- "Find all ways to..."
+- "Count number of solutions..."
+- "Find optimal (min/max/longest/shortest)..."
+- "Is it possible to..."
+- Making sequential decisions with constraints
+
+**2. Problem-Solving Steps:**
+1. Identify if it's DP (overlapping subproblems + optimal substructure)
+2. Define state clearly
+3. Write recurrence relation
+4. Identify base cases
+5. Implement (top-down first, usually easier)
+6. Optimize space if possible
+
+**3. Time vs Space Trade-off:**
+| Approach | Time | Space | Use When |
+|----------|------|-------|----------|
+| Recursion | O(2^n) | O(n) stack | Never in production! |
+| Top-Down | O(n) | O(n) memo + O(n) stack | Easier to code, less optimal |
+| Bottom-Up | O(n) | O(n) table | More optimal, production code |
+| Space-Optimized | O(n) | O(1) | When space is critical |
+
+**4. Common Mistakes to Avoid:**
+
+| Mistake | Problem | Fix |
+|---------|---------|-----|
+| Wrong state definition | Incomplete information | Add necessary parameters to state |
+| Incorrect base case | Wrong results for simple inputs | Test with smallest inputs |
+| Missing states in recurrence | Not considering all transitions | Draw state diagram |
+| Wrong iteration order | Using uncomputed values | Check dependencies |
+| Not initializing DP table | Garbage values | Initialize with 0, -1, or infinity |
+
+### Complexity Analysis Quick Reference
+
+```mermaid
+graph LR
+ Input[Input Size n] --> States[Number of States]
+ States --> Transitions[Transitions per State]
+
+ States --> S1["1D: O(n) states"]
+ States --> S2["2D: O(nΒ²) states"]
+ States --> S3["3D: O(nΒ³) states"]
+
+ Transitions --> T1["O(1) per state"]
+ Transitions --> T2["O(n) per state"]
+
+ S1 --> Time1["Time: O(n) Γ transitions"]
+ S2 --> Time2["Time: O(nΒ²) Γ transitions"]
+
+ style S1 fill:#90EE90
+ style S2 fill:#FFD700
+ style Time1 fill:#E0FFE0
+ style Time2 fill:#FFE0E0
+```
+
+**Time Complexity Formula:**
+```
+Time = (Number of States) Γ (Time per State)
+```
+
+**Space Complexity:**
+- Top-Down: O(number of states) + O(recursion depth)
+- Bottom-Up: O(number of states) or optimized to O(k) where k is constant
+
+### Real Interview Tips
+
+1. **Talk through your thought process:** Explain how you identify it's DP
+2. **Draw examples:** Visualize small cases to find pattern
+3. **Start simple:** Get brute force working, then optimize
+4. **Consider edge cases:** Empty input, single element, all same values
+5. **Optimize later:** First make it work, then make it fast
\ No newline at end of file
diff --git a/algorithms/greedy.md b/algorithms/greedy.md
index 46ef3cc..43d10c4 100644
--- a/algorithms/greedy.md
+++ b/algorithms/greedy.md
@@ -4,6 +4,7 @@ Greedy algorithms make locally optimal choices at each step with the hope of fin
## Table of Contents
- [Understanding Greedy Algorithms](#understanding-greedy-algorithms)
+- [How to Approach Greedy Problems](#how-to-approach-greedy-problems)
- [When to Use Greedy Algorithms](#when-to-use-greedy-algorithms)
- [Common Greedy Algorithm Problems](#common-greedy-algorithm-problems)
- [Greedy vs. Dynamic Programming](#greedy-vs-dynamic-programming)
@@ -42,6 +43,321 @@ Step 3: Choose the largest coin β€ 1: 1
Result: 3 coins [25, 10, 1]
```
+## How to Approach Greedy Problems
+
+### Step 1: Identify if Greedy Works
+
+```mermaid
+graph TD
+ Start[Problem Analysis] --> Q1{Is it an
optimization problem?}
+
+ Q1 -->|No| NotGreedy[Not a greedy problem]
+ Q1 -->|Yes| Q2{Can you make
local optimal choice?}
+
+ Q2 -->|No| DP[Consider Dynamic Programming]
+ Q2 -->|Yes| Q3{Does local optimal
lead to global optimal?}
+
+ Q3 -->|Unsure| Proof[Need to prove
greedy choice property]
+ Q3 -->|Yes| Q4{Has optimal
substructure?}
+
+ Q4 -->|Yes| Greedy[β Use Greedy Algorithm]
+ Q4 -->|No| Reconsider[Reconsider approach]
+
+ Proof --> Test{Can prove or
verify with examples?}
+ Test -->|Yes| Greedy
+ Test -->|No| DP
+
+ style Greedy fill:#90EE90
+ style DP fill:#FFD700
+ style NotGreedy fill:#FFB6C1
+ style Reconsider fill:#FFA500
+```
+
+### Step 2: The Greedy Problem-Solving Framework
+
+#### Phase 1: Understanding & Verification
+
+```
+STEP 1: Identify the Optimization Goal
+β‘ What are we trying to maximize/minimize?
+β‘ Examples: maximum value, minimum cost, maximum activities
+
+STEP 2: Define the Greedy Choice
+β‘ What is the locally optimal choice at each step?
+β‘ Common choices:
+ - Largest/smallest value
+ - Earliest/latest finish time
+ - Best ratio (value/weight)
+ - Closest/farthest distance
+
+STEP 3: Verify Greedy Choice Property
+β‘ Does making the locally optimal choice lead to a globally optimal solution?
+β‘ Methods to verify:
+ - Proof by contradiction
+ - Exchange argument
+ - Mathematical induction
+ - Test with multiple examples
+
+STEP 4: Check for Optimal Substructure
+β‘ After making a greedy choice, is the remaining problem a smaller instance of the same problem?
+β‘ Can we solve the subproblem independently?
+```
+
+#### Phase 2: Implementation Strategy
+
+```mermaid
+graph TD
+ A[Start] --> B[Sort or Organize Data
by greedy criterion]
+ B --> C[Initialize Result]
+ C --> D[Iterate Through Options]
+ D --> E{Is choice
valid & optimal?}
+ E -->|No| D
+ E -->|Yes| F[Make Greedy Choice
Add to result]
+ F --> G{Problem
complete?}
+ G -->|No| D
+ G -->|Yes| H[Return Result]
+
+ style A fill:#FFD700
+ style B fill:#87CEEB
+ style F fill:#90EE90
+ style H fill:#DDA0DD
+```
+
+### Step 3: How to Prove Greedy Works
+
+#### Method 1: Greedy Choice Property (Proof by Contradiction)
+
+```
+Template:
+1. Assume there exists an optimal solution that doesn't include the greedy choice
+2. Show you can modify that solution to include the greedy choice
+3. Prove the modified solution is at least as good as the original
+4. Therefore, a solution with the greedy choice is optimal
+
+Example: Activity Selection
+1. Assume optimal solution O doesn't include activity with earliest finish time (A1)
+2. Let A2 be the first activity in O
+3. Since A1 finishes earliest, we can replace A2 with A1
+4. This still allows all subsequent activities β contradiction
+```
+
+#### Method 2: Exchange Argument
+
+```
+Template:
+1. Take any optimal solution
+2. Show that you can exchange elements to match greedy solution
+3. Prove that each exchange maintains or improves optimality
+4. Therefore, greedy solution is optimal
+
+Example: Fractional Knapsack
+1. Take optimal solution with items not in value/weight ratio order
+2. Exchange lower ratio item with higher ratio item
+3. This increases total value β previous solution wasn't optimal
+4. Therefore, sorting by ratio is correct
+```
+
+#### Method 3: "Staying Ahead" Argument
+
+```
+Template:
+1. Show that after each step, greedy is at least as good as any other solution
+2. Prove this property is maintained throughout
+3. Therefore, at the end, greedy is optimal
+
+Example: Coin Change (standard denominations)
+1. After k coins, greedy uses minimum coins
+2. This property holds for k+1 coins
+3. Therefore, greedy is optimal
+```
+
+### Step 4: Common Greedy Patterns & Decision Making
+
+#### Pattern 1: Selection/Scheduling
+
+```
+Problem indicators:
+- Select maximum number of activities
+- Schedule jobs to minimize time
+- Assign resources efficiently
+
+Greedy criteria to consider:
+β‘ Earliest finish time (Activity Selection)
+β‘ Shortest duration (Shortest Job First)
+β‘ Earliest deadline (Deadline Scheduling)
+β‘ Smallest overlap (Interval Scheduling)
+
+Template:
+1. Sort by chosen criterion
+2. Select first item
+3. For each next item:
+ - If compatible with current selection, add it
+ - Otherwise, skip it
+```
+
+#### Pattern 2: Optimization by Sorting
+
+```
+Problem indicators:
+- Maximize/minimize some value
+- Involves weights, costs, or values
+- Order matters
+
+Greedy criteria to consider:
+β‘ Sort by value (descending for max, ascending for min)
+β‘ Sort by cost or weight
+β‘ Sort by ratio (value/weight)
+
+Template:
+1. Calculate greedy criterion for each element
+2. Sort by criterion
+3. Iterate in sorted order
+4. Make greedy choice at each step
+```
+
+#### Pattern 3: Two-Pointer/Boundary Approach
+
+```
+Problem indicators:
+- Pairs or combinations needed
+- Need to satisfy constraints
+- Work from extremes
+
+Greedy strategy:
+β‘ Start from both ends
+β‘ Move pointers based on greedy choice
+β‘ Make optimal decision at each step
+
+Example: Container With Most Water
+1. Start with widest container (left=0, right=n-1)
+2. Move pointer of shorter height (greedy choice)
+3. Keep track of maximum area
+```
+
+#### Pattern 4: State Change/Transformation
+
+```
+Problem indicators:
+- Transform from one state to another
+- Minimize operations
+- Step-by-step changes
+
+Greedy strategy:
+β‘ Always make the most beneficial change
+β‘ Prefer operations that reduce distance to goal
+β‘ Avoid operations that increase work
+
+Example: Jump Game
+1. Keep track of farthest reachable position
+2. Always update to maximum reachable from current
+3. Greedily extend reach
+```
+
+### Step 5: Testing Your Greedy Solution
+
+#### Verification Checklist
+
+```
+β‘ Test with trivial cases (n=0, n=1, n=2)
+β‘ Test with case where greedy might fail
+β‘ Test with multiple optimal solutions (does greedy find one?)
+β‘ Test with edge cases (all same values, reverse order)
+β‘ Compare with brute force on small inputs
+
+Counter-Example Test Cases:
+1. Does greedy work with unsorted input?
+2. Does greedy work when optimal requires looking ahead?
+3. Does greedy work with negative values?
+4. Does greedy work with duplicate values?
+```
+
+### Decision Flow: Greedy or Not?
+
+```mermaid
+graph TD
+ Start[Optimization Problem] --> Q1{Can identify
clear greedy choice?}
+
+ Q1 -->|No| NotGreedy[Not greedy
Try DP or other]
+ Q1 -->|Yes| Q2{Tested with
examples?}
+
+ Q2 -->|Failed| Q3{Can modify
greedy criteria?}
+ Q2 -->|Passed| Q4{Can prove
correctness?}
+
+ Q3 -->|Yes| Q5[Modify criterion
and retest]
+ Q3 -->|No| DP1[Use Dynamic Programming]
+
+ Q4 -->|Yes| Success[β Greedy works!]
+ Q4 -->|No but intuitive| Q6{Small input size?}
+
+ Q6 -->|Yes| Impl[Implement and test
extensively]
+ Q6 -->|No| Risky[Risky - need proof
or switch to DP]
+
+ Q5 --> Q2
+
+ style Success fill:#90EE90
+ style DP1 fill:#FFD700
+ style NotGreedy fill:#FFB6C1
+ style Risky fill:#FFA500
+ style Impl fill:#87CEEB
+```
+
+### Example: Applying Framework to Jump Game
+
+```
+PROBLEM: Can you reach the last index?
+Array: [2, 3, 1, 1, 4]
+
+STEP 1: Identify Optimization
+Goal: Determine if we can reach the end
+
+STEP 2: Greedy Choice
+At each position, track the farthest position we can reach
+Greedy choice: Always extend reach as far as possible
+
+STEP 3: Verify Greedy Works
+- If we can reach position i, we can reach any j < i
+- If from position i we can reach i+nums[i], we should track this
+- This local choice (max reach) leads to global optimum
+
+STEP 4: Implementation
+max_reach = 0
+for i in range(len(nums)):
+ if i > max_reach:
+ return False # Can't reach this position
+ max_reach = max(max_reach, i + nums[i])
+ if max_reach >= len(nums) - 1:
+ return True
+return False
+
+STEP 5: Verify
+- [2,3,1,1,4]: max_reach progresses: 2β4β4β4β8 β
+- [3,2,1,0,4]: max_reach progresses: 3β3β3β3 β
+```
+
+### Common Pitfalls When Using Greedy
+
+```
+1. ASSUMING GREEDY WORKS WITHOUT PROOF
+ β Just because it seems logical doesn't mean it's correct
+ β Always verify with examples and try to prove
+
+2. FORGETTING TO SORT
+ β Greedy often requires sorted input
+ β Identify the sorting criterion first
+
+3. NOT CHECKING ALL CONSTRAINTS
+ β Local optimum must satisfy all constraints
+ β Validate each greedy choice
+
+4. CONFUSING GREEDY WITH DP
+ β If you need to look at multiple future states, it's probably DP
+ β Greedy makes decisions based on current information only
+
+5. NOT TESTING EDGE CASES
+ β Greedy can fail on specific inputs
+ β Test thoroughly, especially edge cases
+```
+
## When to Use Greedy Algorithms
### Good Candidates for Greedy Approach
diff --git a/algorithms/sorting.md b/algorithms/sorting.md
index 3d45726..a1b4ab1 100644
--- a/algorithms/sorting.md
+++ b/algorithms/sorting.md
@@ -57,6 +57,71 @@ Before diving into sorting algorithms, you should understand:
*Note: n is the number of elements, k is the range of elements*
+### Sorting Algorithm Selection Guide
+
+```mermaid
+graph TD
+ Start[Need to Sort?] --> Q1{What is data size?}
+
+ Q1 -->|Small n < 50| Q2{Nearly sorted?}
+ Q1 -->|Medium-Large| Q3{What constraints?}
+
+ Q2 -->|Yes| Insertion["Insertion Sort
O(n) best case
Simple, stable"]
+ Q2 -->|No| Simple["Bubble/Selection Sort
O(nΒ²) but simple
Use for learning"]
+
+ Q3 -->|Memory limited| Q4{Need stability?}
+ Q3 -->|Speed critical| Quick["Quick Sort
O(n log n) average
Fast in practice"]
+
+ Q4 -->|Yes, need stable| Merge["Merge Sort
O(n log n) guaranteed
Stable, uses O(n) space"]
+ Q4 -->|No, can be unstable| Heap["Heap Sort
O(n log n) guaranteed
In-place, O(1) space"]
+
+ Q3 -->|Limited range| Q5{Integers only?}
+ Q5 -->|Yes| Q6{Range size?}
+ Q6 -->|Small k| Counting["Counting Sort
O(n+k)
Non-comparison sort"]
+ Q6 -->|Large k| Radix["Radix Sort
O(nk)
Digit by digit"]
+
+ style Insertion fill:#90EE90
+ style Quick fill:#FFD700
+ style Merge fill:#87CEEB
+ style Heap fill:#DDA0DD
+ style Counting fill:#FFB6C1
+ style Radix fill:#F0E68C
+ style Simple fill:#FFA500
+```
+
+### Sorting Algorithm Properties
+
+```mermaid
+graph LR
+ subgraph "Comparison-Based O(n log n)"
+ Merge[Merge Sort
Stable β
In-place β
Space: O n]
+ Quick[Quick Sort
Stable β
In-place β
Space: O log n]
+ Heap[Heap Sort
Stable β
In-place β
Space: O 1]
+ end
+
+ subgraph "Simple O(nΒ²)"
+ Bubble[Bubble Sort
Stable β
In-place β
Best: O n]
+ Selection[Selection Sort
Stable β
In-place β
Always: O nΒ²]
+ Insert[Insertion Sort
Stable β
In-place β
Best: O n]
+ end
+
+ subgraph "Non-Comparison O(n+k)"
+ Count[Counting Sort
Stable β
Limited range]
+ Radix[Radix Sort
Stable β
Integers/Strings]
+ Bucket[Bucket Sort
Stable β
Uniform distribution]
+ end
+
+ style Merge fill:#87CEEB
+ style Quick fill:#FFD700
+ style Heap fill:#DDA0DD
+ style Bubble fill:#FFE4B5
+ style Selection fill:#FFA500
+ style Insert fill:#90EE90
+ style Count fill:#FFB6C1
+ style Radix fill:#F0E68C
+ style Bucket fill:#E0FFE0
+```
+
## Bubble Sort
### Difficulty: β
ββββ (Easy)
diff --git a/big-o-notation.md b/big-o-notation.md
index 580b783..4ae9ff3 100644
--- a/big-o-notation.md
+++ b/big-o-notation.md
@@ -17,38 +17,86 @@ Big O Notation is a mathematical notation that describes the limiting behavior o
## Visual Representation
+### Complexity Growth Comparison
+
+```mermaid
+graph TD
+ A[Algorithm Complexity] --> B[Excellent]
+ A --> C[Good]
+ A --> D[Fair]
+ A --> E[Poor]
+ A --> F[Very Poor]
+
+ B --> B1["O(1) - Constant
Array access, hash lookup"]
+ B --> B2["O(log n) - Logarithmic
Binary search"]
+
+ C --> C1["O(n) - Linear
Linear search, array traversal"]
+ C --> C2["O(n log n) - Linearithmic
Merge sort, quick sort"]
+
+ D --> D1["O(nΒ²) - Quadratic
Bubble sort, nested loops"]
+
+ E --> E1["O(2βΏ) - Exponential
Recursive Fibonacci"]
+
+ F --> F1["O(n!) - Factorial
Traveling salesman (brute force)"]
+
+ style B fill:#90EE90
+ style C fill:#FFD700
+ style D fill:#FFA500
+ style E fill:#FF6347
+ style F fill:#8B0000,color:#fff
```
- β
- β
- β O(n!)
- β β
- β β
- β β
- β β
- β β
- β β
- β β
- β β
- β β O(2βΏ)
- β β β
- β β β
- β β β
- β β β O(nΒ²)
- β β β
- β β β
- β β β O(n log n)
- β β β β
- β β β β
- β β β β O(n)
- β β β β
- β β β β
- β β β β O(log n)
- β β β β β
- β β β β O(1)
- βββββββββββββββββββββββββββββββββββββββββββββββ
- Input Size (n)
+
+### Complexity Decision Tree
+
+When analyzing an algorithm, use this decision tree to determine its time complexity:
+
+```mermaid
+graph TD
+ Start[Start: Analyze Algorithm] --> Q1{Does it access
data by index/key?}
+ Q1 -->|Yes, no loops| O1[O1 - Constant Time]
+ Q1 -->|No| Q2{Does it divide
input in half
each iteration?}
+
+ Q2 -->|Yes| Ologn[O log n - Logarithmic]
+ Q2 -->|No| Q3{Does it iterate
through input once?}
+
+ Q3 -->|Yes, single loop| On[O n - Linear]
+ Q3 -->|No| Q4{Does it divide and
conquer with merging?}
+
+ Q4 -->|Yes| Onlogn[O n log n - Linearithmic]
+ Q4 -->|No| Q5{Are there
nested loops?}
+
+ Q5 -->|2 nested loops| On2[O nΒ² - Quadratic]
+ Q5 -->|3 nested loops| On3[O nΒ³ - Cubic]
+ Q5 -->|No| Q6{Does it make
recursive calls
branching 2+?}
+
+ Q6 -->|Yes| O2n[O 2βΏ - Exponential]
+ Q6 -->|No| Q7{Does it generate
all permutations?}
+
+ Q7 -->|Yes| Onf[O n! - Factorial]
+ Q7 -->|No| Custom[Custom Analysis Needed]
+
+ style O1 fill:#90EE90
+ style Ologn fill:#90EE90
+ style On fill:#FFD700
+ style Onlogn fill:#FFD700
+ style On2 fill:#FFA500
+ style On3 fill:#FF6347
+ style O2n fill:#FF6347
+ style Onf fill:#8B0000,color:#fff
```
+### Growth Rate Visualization
+
+As input size grows, here's how different complexities scale:
+
+| n | O(1) | O(log n) | O(n) | O(n log n) | O(nΒ²) | O(2βΏ) |
+|---|------|----------|------|------------|-------|-------|
+| 1 | 1 | 0 | 1 | 0 | 1 | 2 |
+| 10 | 1 | 3 | 10 | 30 | 100 | 1,024 |
+| 100 | 1 | 7 | 100 | 700 | 10,000 | 1.27Γ10Β³β° |
+| 1,000 | 1 | 10 | 1,000 | 10,000 | 1,000,000 | β |
+| 10,000 | 1 | 13 | 10,000 | 130,000 | 100,000,000 | β |
+
## Examples in Python and JavaScript
### O(1) - Constant Time
diff --git a/data-structures/arrays.md b/data-structures/arrays.md
index 409070e..c811332 100644
--- a/data-structures/arrays.md
+++ b/data-structures/arrays.md
@@ -4,11 +4,61 @@ Arrays are one of the most fundamental data structures in computer science. They
## Visual Representation
+### Array Structure
+
+```mermaid
+graph LR
+ subgraph "Array: [10, 20, 30, 40, 50, 60]"
+ A0["Index: 0
Value: 10"]
+ A1["Index: 1
Value: 20"]
+ A2["Index: 2
Value: 30"]
+ A3["Index: 3
Value: 40"]
+ A4["Index: 4
Value: 50"]
+ A5["Index: 5
Value: 60"]
+ end
+ A0 -.Contiguous Memory.-> A1 -.-> A2 -.-> A3 -.-> A4 -.-> A5
+
+ style A0 fill:#e1f5ff
+ style A1 fill:#e1f5ff
+ style A2 fill:#e1f5ff
+ style A3 fill:#e1f5ff
+ style A4 fill:#e1f5ff
+ style A5 fill:#e1f5ff
```
-Index: 0 1 2 3 4 5
- ββββββ¬βββββ¬βββββ¬βββββ¬βββββ¬βββββ
-Array: β 10 β 20 β 30 β 40 β 50 β 60 β
- ββββββ΄βββββ΄βββββ΄βββββ΄βββββ΄βββββ
+
+### Array Operations Flowchart
+
+```mermaid
+graph TD
+ Start[Array Operation] --> Q1{What operation?}
+
+ Q1 -->|Access| Access[Access by Index]
+ Q1 -->|Insert| Q2{Where to insert?}
+ Q1 -->|Delete| Q3{Where to delete?}
+ Q1 -->|Search| Q4{Is array sorted?}
+
+ Access --> AccessTime["O(1) - Direct access
arr[index]"]
+
+ Q2 -->|At end| InsertEnd["O(1) - Append
No shifting needed"]
+ Q2 -->|At beginning| InsertStart["O(n) - Prepend
Shift all elements right"]
+ Q2 -->|In middle| InsertMiddle["O(n) - Insert
Shift elements from index"]
+
+ Q3 -->|At end| DeleteEnd["O(1) - Pop
No shifting needed"]
+ Q3 -->|At beginning| DeleteStart["O(n) - Remove first
Shift all elements left"]
+ Q3 -->|In middle| DeleteMiddle["O(n) - Remove
Shift elements from index"]
+
+ Q4 -->|Yes| SearchSorted["O(log n)
Binary Search"]
+ Q4 -->|No| SearchUnsorted["O(n)
Linear Search"]
+
+ style AccessTime fill:#90EE90
+ style InsertEnd fill:#90EE90
+ style DeleteEnd fill:#90EE90
+ style InsertStart fill:#FFA500
+ style DeleteStart fill:#FFA500
+ style InsertMiddle fill:#FFA500
+ style DeleteMiddle fill:#FFA500
+ style SearchSorted fill:#FFD700
+ style SearchUnsorted fill:#FFD700
```
## Types of Arrays
@@ -227,6 +277,25 @@ console.log(linearSearch(arr, 9)); // Output: 2
### 2. Binary Search (for sorted arrays)
+#### Visual Step-by-Step Binary Search
+
+```mermaid
+graph TD
+ Start["Array: [1, 2, 3, 4, 5, 6, 7, 8, 9]
Target: 7"] --> Step1
+ Step1["Step 1: left=0, right=8
mid=4, arr[4]=5
5 < 7, search right half"] --> Step2
+ Step2["Step 2: left=5, right=8
mid=6, arr[6]=7
Found! Return index 6"] --> Found["β Target found at index 6"]
+
+ Start2["Array: [1, 2, 3, 4, 5, 6, 7, 8, 9]
Target: 10"] --> S1
+ S1["Step 1: left=0, right=8
mid=4, arr[4]=5
5 < 10, search right half"] --> S2
+ S2["Step 2: left=5, right=8
mid=6, arr[6]=7
7 < 10, search right half"] --> S3
+ S3["Step 3: left=7, right=8
mid=7, arr[7]=8
8 < 10, search right half"] --> S4
+ S4["Step 4: left=8, right=8
mid=8, arr[8]=9
9 < 10, search right half"] --> S5
+ S5["Step 5: left=9, right=8
left > right"] --> NotFound["β Target not found, return -1"]
+
+ style Found fill:#90EE90
+ style NotFound fill:#FFB6C6
+```
+
**Python:**
```python
def binary_search(arr, target):
diff --git a/data-structures/graphs.md b/data-structures/graphs.md
index 88838e4..dc5c216 100644
--- a/data-structures/graphs.md
+++ b/data-structures/graphs.md
@@ -4,26 +4,74 @@ A graph is a non-linear data structure consisting of nodes (vertices) and edges
## Visual Representation
+### Undirected Graph
+
+```mermaid
+graph LR
+ A((A)) --- B((B))
+ A --- C((C))
+ B --- D((D))
+ C --- D
+ D --- E((E))
+
+ style A fill:#FFD700
+ style B fill:#87CEEB
+ style C fill:#90EE90
+ style D fill:#FFB6C1
+ style E fill:#DDA0DD
```
-Undirected Graph:
- A --- B
- | |
- | |
- C --- D --- E
-
-Directed Graph:
- A --β B
- β β
- | |
- C β-- D --β E
-
-Weighted Graph:
- A ---5--- B
- | |
- | |
- 2 3
- | |
- C ---1--- D ---4--- E
+
+### Directed Graph (Digraph)
+
+```mermaid
+graph TD
+ A((A)) --> B((B))
+ B --> D((D))
+ D --> E((E))
+ D --> C((C))
+ C --> A
+
+ style A fill:#FFD700
+ style B fill:#87CEEB
+ style C fill:#90EE90
+ style D fill:#FFB6C1
+ style E fill:#DDA0DD
+```
+
+### Weighted Graph
+
+```mermaid
+graph LR
+ A((A)) ---|5| B((B))
+ A ---|2| C((C))
+ B ---|3| D((D))
+ C ---|1| D
+ D ---|4| E((E))
+
+ style A fill:#FFD700
+ style B fill:#87CEEB
+ style C fill:#90EE90
+ style D fill:#FFB6C1
+ style E fill:#DDA0DD
+```
+
+### Graph Traversal Comparison
+
+```mermaid
+graph TD
+ Start[Graph Traversal] --> Q1{Which algorithm?}
+
+ Q1 -->|DFS| DFS[Depth-First Search]
+ Q1 -->|BFS| BFS[Breadth-First Search]
+
+ DFS --> DFS_Desc["Uses: Stack or Recursion
Order: Go deep first
Applications:
- Detect cycles
- Topological sort
- Path finding
- Connected components"]
+
+ BFS --> BFS_Desc["Uses: Queue
Order: Level by level
Applications:
- Shortest path (unweighted)
- Level order traversal
- Connected components
- Bipartite checking"]
+
+ style DFS fill:#FFE4B5
+ style BFS fill:#E0FFE0
+ style DFS_Desc fill:#FFE4B5
+ style BFS_Desc fill:#E0FFE0
```
## Types of Graphs
diff --git a/data-structures/hash-tables.md b/data-structures/hash-tables.md
index 511bacf..0fb6215 100644
--- a/data-structures/hash-tables.md
+++ b/data-structures/hash-tables.md
@@ -4,31 +4,62 @@ A hash table (also known as a hash map) is a data structure that implements an a
## Visual Representation
+### Hash Table Structure
+
+```mermaid
+graph TD
+ subgraph "Hash Table with Separate Chaining"
+ Key1["Key: 'John'"] --> Hash1[Hash Function]
+ Hash1 --> Index1["Index: 1"]
+ Index1 --> Bucket1["'John': 25"]
+
+ Key2["Key: 'Sarah'"] --> Hash2[Hash Function]
+ Hash2 --> Index3["Index: 3"]
+ Index3 --> Bucket3A["'Sarah': 30"]
+ Bucket3A -.Collision!.-> Bucket3B["'Mike': 35"]
+
+ Key3["Key: 'Lisa'"] --> Hash3[Hash Function]
+ Hash3 --> Index5["Index: 5"]
+ Index5 --> Bucket5["'Lisa': 28"]
+ end
+
+ style Bucket3A fill:#FFB6C6
+ style Bucket3B fill:#FFB6C6
+ style Bucket1 fill:#90EE90
+ style Bucket5 fill:#90EE90
```
-βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-β Hash Table β
-βββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
-β Index β Bucket β β
-βββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β
-β 0 β β β
-βββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β
-β 1 β βββββββββββββββ β β
-β β β "John": 25 β β β
-β β βββββββββββββββ β β
-βββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β
-β 2 β β β
-βββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β
-β 3 β βββββββββββββββ βββββββββββββββ β β
-β β β "Sarah": 30 ββ β "Mike": 35 β β β
-β β βββββββββββββββ βββββββββββββββ β β
-βββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β
-β 4 β β β
-βββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β
-β 5 β βββββββββββββββ β β
-β β β "Lisa": 28 β β β
-β β βββββββββββββββ β β
-βββββββββ΄ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
-βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+
+### Hash Function Process
+
+```mermaid
+graph LR
+ Input["Input Key:
'hello'"] --> Hash["Hash Function
h(key) = sum(ASCII) % size"]
+ Hash --> Computation["104+101+108+108+111 = 532
532 % 10 = 2"]
+ Computation --> Index["Index: 2"]
+ Index --> Access["Access bucket[2]"]
+
+ style Hash fill:#FFD700
+ style Index fill:#90EE90
+```
+
+### Collision Resolution Methods
+
+```mermaid
+graph TD
+ Collision[Collision Detected] --> Method{Resolution Method?}
+
+ Method -->|Separate Chaining| Chain["Linked List at Bucket
β’ Each bucket = linked list
β’ Add to list
β’ O(n) worst case lookup"]
+
+ Method -->|Open Addressing| Open["Probe for Empty Slot
β’ Linear probing
β’ Quadratic probing
β’ Double hashing"]
+
+ Chain --> ChainPros["Pros:
β Simple
β No clustering
β Can exceed load factor"]
+
+ Open --> OpenPros["Pros:
β Better cache
β No pointers
β Less memory"]
+
+ style Chain fill:#87CEEB
+ style Open fill:#FFD700
+ style ChainPros fill:#90EE90
+ style OpenPros fill:#90EE90
```
## Key Components
diff --git a/data-structures/heaps.md b/data-structures/heaps.md
index 90a4caa..384b58a 100644
--- a/data-structures/heaps.md
+++ b/data-structures/heaps.md
@@ -4,30 +4,109 @@ A heap is a specialized tree-based data structure that satisfies the heap proper
## Visual Representation
+### Max Heap Structure
+
+```mermaid
+graph TD
+ Root["9
(Root - Maximum)"] --> L1_L["7"]
+ Root --> L1_R["8"]
+ L1_L --> L2_LL["5"]
+ L1_L --> L2_LR["6"]
+ L1_R --> L2_RL["4"]
+ L1_R --> L2_RR["3"]
+
+ Note["Max Heap Property:
Parent β₯ Children"]
+
+ style Root fill:#FFD700
+ style L1_L fill:#90EE90
+ style L1_R fill:#90EE90
+ style Note fill:#FFE4B5
```
-Max Heap:
- βββββ
- β 9 β
- βββ¬ββ
- ββββββ΄βββββ
- ββββ΄βββ ββββ΄βββ
- β 7 β β 8 β
- ββββ¬βββ ββββ¬βββ
- ββββ΄βββ ββββ΄βββ
- β 5 β β 6 β
- βββββββ βββββββ
-
-Min Heap:
- βββββ
- β 1 β
- βββ¬ββ
- ββββββ΄βββββ
- ββββ΄βββ ββββ΄βββ
- β 2 β β 3 β
- ββββ¬βββ ββββ¬βββ
- ββββ΄βββ ββββ΄βββ
- β 4 β β 5 β
- βββββββ βββββββ
+
+### Min Heap Structure
+
+```mermaid
+graph TD
+ Root["1
(Root - Minimum)"] --> L1_L["2"]
+ Root --> L1_R["3"]
+ L1_L --> L2_LL["4"]
+ L1_L --> L2_LR["5"]
+ L1_R --> L2_RL["6"]
+ L1_R --> L2_RR["7"]
+
+ Note["Min Heap Property:
Parent β€ Children"]
+
+ style Root fill:#87CEEB
+ style L1_L fill:#90EE90
+ style L1_R fill:#90EE90
+ style Note fill:#FFE4B5
+```
+
+### Heap Operations Visual
+
+```mermaid
+graph TD
+ subgraph "Insert Operation"
+ I1["1. Add to bottom"] --> I2["2. Bubble up"]
+ I2 --> I3["3. Compare with parent"]
+ I3 --> I4{Violates
heap property?}
+ I4 -->|Yes| I5["Swap with parent"]
+ I5 --> I3
+ I4 -->|No| I6["β Done - O(log n)"]
+ end
+
+ subgraph "Extract Min/Max"
+ E1["1. Save root value"] --> E2["2. Move last to root"]
+ E2 --> E3["3. Bubble down"]
+ E3 --> E4{Violates
heap property?}
+ E4 -->|Yes| E5["Swap with smaller/larger child"]
+ E5 --> E3
+ E4 -->|No| E6["β Done - O(log n)"]
+ end
+
+ style I6 fill:#90EE90
+ style E6 fill:#90EE90
+```
+
+### Heap vs Other Structures
+
+```mermaid
+graph TD
+ Problem[Problem Type] --> Q1{Need quick access
to min or max?}
+
+ Q1 -->|Yes| Q2{Need both
min AND max?}
+ Q1 -->|Need sorted| BST["Use BST
O(log n) for all ops
Maintains sorted order"]
+
+ Q2 -->|Only min OR max| Heap["β Use Heap
O(1) peek min/max
O(log n) insert/extract"]
+
+ Q2 -->|Need both| TwoHeaps["β Use Two Heaps
Max heap + Min heap
Find median in O(1)"]
+
+ Q2 -->|Need all sorted| PQ["Use Priority Queue
(implemented with heap)
Extract in sorted order"]
+
+ style Heap fill:#90EE90
+ style TwoHeaps fill:#FFD700
+ style BST fill:#87CEEB
+ style PQ fill:#FFB6C1
+```
+
+### Heap Array Representation
+
+```mermaid
+graph LR
+ subgraph "Array: [9, 7, 8, 5, 6, 4, 3]"
+ A0["Index 0
Value: 9
Root"]
+ A1["Index 1
Value: 7
Left child"]
+ A2["Index 2
Value: 8
Right child"]
+ A3["Index 3
Value: 5"]
+ A4["Index 4
Value: 6"]
+ end
+
+ Formulas["Parent: (i-1)/2
Left child: 2i+1
Right child: 2i+2"]
+
+ style A0 fill:#FFD700
+ style A1 fill:#90EE90
+ style A2 fill:#90EE90
+ style Formulas fill:#FFE4B5
```
## Key Operations
diff --git a/data-structures/linked-lists.md b/data-structures/linked-lists.md
index 48a7593..2faacf1 100644
--- a/data-structures/linked-lists.md
+++ b/data-structures/linked-lists.md
@@ -4,21 +4,58 @@ A linked list is a linear data structure where elements are stored in nodes, and
## Visual Representation
+### Singly Linked List Structure
+
+```mermaid
+graph LR
+ Head[Head] --> N1
+ N1["Node 1
Value: 10
Next: β"] --> N2["Node 2
Value: 20
Next: β"]
+ N2 --> N3["Node 3
Value: 30
Next: β"]
+ N3 --> N4["Node 4
Value: 40
Next: β"]
+ N4 --> NULL[NULL]
+ N4 -.Tail.-> Tail[Tail]
+
+ style N1 fill:#e1f5ff
+ style N2 fill:#e1f5ff
+ style N3 fill:#e1f5ff
+ style N4 fill:#e1f5ff
+ style NULL fill:#ffcccc
```
-Singly Linked List:
-ββββββββββ ββββββββββ ββββββββββ ββββββββββ
-β Value: 1β β Value: 2β β Value: 3β β Value: 4β
-β Next: βββΌββββΊβ Next: βββΌββββΊβ Next: βββΌββββΊβ Next: βββΌββββΊ NULL
-ββββββββββ ββββββββββ ββββββββββ ββββββββββ
- Head Tail
-
-Doubly Linked List:
-βββββββββββββββ βββββββββββββββ βββββββββββββββ
-β Prev: NULL β β Prev: βββββββΌβββββ Prev: βββββββΌββββ
-β Value: 1 β β Value: 2 β β Value: 3 β
-β Next: βββββββΌββββΊβ Next: βββββββΌββββΊβ Next: NULL β
-βββββββββββββββ βββββββββββββββ βββββββββββββββ
- Head Tail
+
+### Doubly Linked List Structure
+
+```mermaid
+graph LR
+ NULL1[NULL] --> N1
+ Head[Head] -.-> N1
+ N1["Node 1
β Prev | Value: 10 | Next β"] <--> N2["Node 2
β Prev | Value: 20 | Next β"]
+ N2 <--> N3["Node 3
β Prev | Value: 30 | Next β"]
+ N3 <--> N4["Node 4
β Prev | Value: 40 | Next β"]
+ N4 --> NULL2[NULL]
+ N4 -.Tail.-> Tail[Tail]
+
+ style N1 fill:#ffe1ff
+ style N2 fill:#ffe1ff
+ style N3 fill:#ffe1ff
+ style N4 fill:#ffe1ff
+ style NULL1 fill:#ffcccc
+ style NULL2 fill:#ffcccc
+```
+
+### Circular Linked List Structure
+
+```mermaid
+graph LR
+ Head[Head] --> N1
+ N1["Node 1
Value: 10
Next: β"] --> N2["Node 2
Value: 20
Next: β"]
+ N2 --> N3["Node 3
Value: 30
Next: β"]
+ N3 --> N4["Node 4
Value: 40
Next: β"]
+ N4 --> N1
+
+ style N1 fill:#e1ffe1
+ style N2 fill:#e1ffe1
+ style N3 fill:#e1ffe1
+ style N4 fill:#e1ffe1
```
## Types of Linked Lists
@@ -527,6 +564,21 @@ console.log(doublyLinkedList.printList()); // Output: [5, 10, 20]
### 1. Reverse a Linked List
+#### Visual Step-by-Step Reversal
+
+```mermaid
+graph TD
+ Start["Initial List
1 β 2 β 3 β 4 β NULL"] --> Step1
+ Step1["Step 1: prev=NULL, curr=1
NULL β 1 2 β 3 β 4 β NULL"] --> Step2
+ Step2["Step 2: prev=1, curr=2
NULL β 1 β 2 3 β 4 β NULL"] --> Step3
+ Step3["Step 3: prev=2, curr=3
NULL β 1 β 2 β 3 4 β NULL"] --> Step4
+ Step4["Step 4: prev=3, curr=4
NULL β 1 β 2 β 3 β 4"] --> Result
+ Result["Final Result
4 β 3 β 2 β 1 β NULL
New Head = 4"]
+
+ style Start fill:#e1f5ff
+ style Result fill:#90EE90
+```
+
**Python:**
```python
def reverse_linked_list(head):
@@ -569,6 +621,23 @@ function reverseLinkedList(head) {
### 2. Detect a Cycle in a Linked List
+#### Floyd's Cycle Detection (Tortoise and Hare)
+
+```mermaid
+graph TD
+ Start["Floyd's Cycle Detection
Slow moves 1 step, Fast moves 2 steps"] --> Check{Do they meet?}
+
+ Check -->|No, Fast reaches NULL| NoCycle["No Cycle
Fast reached end"]
+ Check -->|Yes, they meet| HasCycle["Cycle Detected!
They met at same node"]
+
+ Example1["Example 1: No Cycle
1 β 2 β 3 β 4 β NULL
Slow: 1β2β3, Fast: 1β3βNULL"] --> NoCycle
+
+ Example2["Example 2: Has Cycle
1 β 2 β 3 β 4 β΄
β___________|
Slow: 1β2β3β4β2β3
Fast: 1β3β2β4β3β2
Meet at node 3"] --> HasCycle
+
+ style NoCycle fill:#90EE90
+ style HasCycle fill:#FFD700
+```
+
**Python:**
```python
def has_cycle(head):
diff --git a/data-structures/queues.md b/data-structures/queues.md
index e038d59..05bf215 100644
--- a/data-structures/queues.md
+++ b/data-structures/queues.md
@@ -21,6 +21,257 @@ A queue is a linear data structure that follows the First In, First Out (FIFO) p
4. **isEmpty**: Check if the queue is empty
5. **Size**: Get the number of elements in the queue
+## How to Approach Queue Problems
+
+### Step 1: Identify if a Queue is Needed
+
+```mermaid
+graph TD
+ Start[Problem Analysis] --> Q1{Need to process
in FIFO order?}
+
+ Q1 -->|Yes| Queue1[β Use Queue
Simple Queue]
+ Q1 -->|No| Q2{Level-by-level
processing?}
+
+ Q2 -->|Yes| Queue2[β Use Queue
BFS Pattern]
+ Q2 -->|No| Q3{Need to track
order of arrival?}
+
+ Q3 -->|Yes| Q4{Priority-based
processing?}
+ Q3 -->|No| Other[Consider other
data structures]
+
+ Q4 -->|Yes| PQ[β Use Priority Queue
Heap-based]
+ Q4 -->|No| Queue3[β Use Simple Queue]
+
+ style Queue1 fill:#90EE90
+ style Queue2 fill:#90EE90
+ style Queue3 fill:#90EE90
+ style PQ fill:#FFD700
+ style Other fill:#FFB6C1
+```
+
+### Step 2: Choose the Right Queue Type
+
+```mermaid
+graph TD
+ Start[Queue Problem] --> Q1{Need priority
ordering?}
+
+ Q1 -->|Yes| Priority[Priority Queue
Use: Task scheduling,
merge k sorted lists]
+ Q1 -->|No| Q2{Need access to
both ends?}
+
+ Q2 -->|Yes| Deque[Double-ended Queue
Use: Sliding window max,
palindrome checks]
+ Q2 -->|No| Q3{Fixed size buffer?}
+
+ Q3 -->|Yes| Circular[Circular Queue
Use: Ring buffers,
resource pooling]
+ Q3 -->|No| Q4{Simple FIFO?}
+
+ Q4 -->|Yes| Simple[Simple Queue
Use: BFS, level order,
task queues]
+
+ style Priority fill:#FFD700
+ style Deque fill:#87CEEB
+ style Circular fill:#DDA0DD
+ style Simple fill:#90EE90
+```
+
+### Step 3: Common Queue Problem Patterns
+
+#### Pattern 1: Level-Order Traversal (BFS)
+
+```
+Problem indicators:
+- Process tree/graph level by level
+- Find shortest path in unweighted graph
+- Explore all neighbors before going deeper
+
+Approach:
+1. Initialize queue with starting node
+2. Mark starting node as visited
+3. While queue not empty:
+ - Dequeue front element
+ - Process current element
+ - Enqueue all unvisited neighbors
+ - Mark neighbors as visited
+
+Template:
+queue = [start_node]
+visited = {start_node}
+
+while queue:
+ current = queue.pop(0)
+ process(current)
+
+ for neighbor in get_neighbors(current):
+ if neighbor not in visited:
+ visited.add(neighbor)
+ queue.append(neighbor)
+```
+
+#### Pattern 2: Sliding Window with Queue
+
+```
+Problem indicators:
+- Find max/min in sliding windows
+- Track elements in a range
+- Need to maintain order
+
+Approach:
+1. Use deque to store indices or values
+2. Maintain deque in sorted order (increasing or decreasing)
+3. Remove elements outside current window
+4. Front of deque always has answer
+
+Template:
+from collections import deque
+
+dq = deque()
+result = []
+
+for i in range(len(arr)):
+ # Remove elements outside window
+ while dq and dq[0] < i - k + 1:
+ dq.popleft()
+
+ # Maintain order (e.g., decreasing for max)
+ while dq and arr[dq[-1]] < arr[i]:
+ dq.pop()
+
+ dq.append(i)
+
+ # Add result when window is complete
+ if i >= k - 1:
+ result.append(arr[dq[0]])
+```
+
+#### Pattern 3: Multi-Source BFS
+
+```
+Problem indicators:
+- Multiple starting points
+- Need minimum distance from any source
+- Simultaneous expansion
+
+Approach:
+1. Initialize queue with ALL sources
+2. Process all sources simultaneously
+3. Track distance/level for each cell
+4. Stop when target found or queue empty
+
+Template:
+queue = deque()
+visited = set()
+
+# Add all sources to queue
+for source in sources:
+ queue.append((source, 0)) # (node, distance)
+ visited.add(source)
+
+while queue:
+ node, dist = queue.popleft()
+
+ if is_target(node):
+ return dist
+
+ for neighbor in get_neighbors(node):
+ if neighbor not in visited:
+ visited.add(neighbor)
+ queue.append((neighbor, dist + 1))
+```
+
+#### Pattern 4: Priority Queue for Scheduling
+
+```
+Problem indicators:
+- Process tasks by priority
+- Merge multiple sorted sequences
+- Always need min/max element
+
+Approach:
+1. Use heapq (priority queue)
+2. Push elements with priority
+3. Always pop minimum priority element
+4. Re-insert if needed
+
+Template:
+import heapq
+
+pq = []
+
+# Add tasks with priority
+for task in tasks:
+ heapq.heappush(pq, (priority, task))
+
+# Process in priority order
+while pq:
+ priority, task = heapq.heappop(pq)
+ process(task)
+
+ # Re-insert if needed
+ if needs_rescheduling(task):
+ heapq.heappush(pq, (new_priority, task))
+```
+
+### Step 4: Problem-Solving Decision Tree
+
+```mermaid
+graph TD
+ Problem[Queue Problem] --> Type{Problem Type?}
+
+ Type -->|Graph/Tree| BFS[Use BFS with Queue]
+ Type -->|Sliding Window| Window{Need min/max
in window?}
+ Type -->|Scheduling| Sched{Priority needed?}
+ Type -->|Simulation| Sim[Use Simple Queue
for events]
+
+ BFS --> Single{Single or
multiple sources?}
+ Single -->|Single| BFS1[Standard BFS]
+ Single -->|Multiple| BFS2[Multi-source BFS]
+
+ Window -->|Yes| Deque1[Use Monotonic Deque]
+ Window -->|No| Deque2[Use Simple Deque]
+
+ Sched -->|Yes| PQ[Use Priority Queue
Min Heap]
+ Sched -->|No| FIFO[Use Simple Queue
FIFO]
+
+ style BFS1 fill:#90EE90
+ style BFS2 fill:#87CEEB
+ style Deque1 fill:#FFD700
+ style Deque2 fill:#DDA0DD
+ style PQ fill:#FFA500
+ style FIFO fill:#90EE90
+```
+
+### Step 5: When to Use Which Queue
+
+| Scenario | Queue Type | Why | Example Problems |
+|----------|-----------|-----|-----------------|
+| BFS traversal | Simple Queue | FIFO order | Binary tree level order |
+| Task scheduling | Priority Queue | Order by priority | CPU scheduling, Merge k sorted |
+| Sliding window max/min | Deque | Access both ends | Max in sliding window |
+| Fixed-size buffer | Circular Queue | Memory efficiency | Stream processing |
+| Need to remove from both ends | Deque | Flexibility | Palindrome check |
+| Process events in order | Simple Queue | Sequential processing | Print queue |
+
+### Step 6: Common Mistakes to Avoid
+
+```
+1. USING WRONG QUEUE TYPE
+ β Using list.pop(0) instead of deque.popleft() in Python
+ β Always use collections.deque for efficient O(1) operations
+
+2. FORGETTING TO MARK AS VISITED IN BFS
+ β This causes infinite loops or revisiting nodes
+ β Always maintain a visited set
+
+3. PROCESSING QUEUE INCORRECTLY IN LEVEL-ORDER
+ β Not tracking level boundaries properly
+ β Store level size before processing each level
+
+4. NOT HANDLING EMPTY QUEUE
+ β Trying to dequeue from empty queue
+ β Always check if queue is empty before dequeueing
+
+5. PRIORITY QUEUE DIRECTION CONFUSION
+ β Python's heapq is min-heap by default
+ β Negate values for max-heap behavior
+```
+
## Implementation in Python and JavaScript
### Python
diff --git a/data-structures/stacks.md b/data-structures/stacks.md
index 87cab8e..32d4e74 100644
--- a/data-structures/stacks.md
+++ b/data-structures/stacks.md
@@ -4,14 +4,65 @@ A stack is a linear data structure that follows the Last In, First Out (LIFO) pr
## Visual Representation
+### Stack Structure (LIFO)
+
+```mermaid
+graph TD
+ Top["TOP β Operations happen here"] --> E3["30
(Last In)"]
+ E3 --> E2["20"]
+ E2 --> E1["10
(First In)"]
+ E1 --> Bottom["BOTTOM"]
+
+ style Top fill:#FFD700
+ style E3 fill:#90EE90
+ style E2 fill:#87CEEB
+ style E1 fill:#FFB6C1
```
- ββββββ
- β 30 β β Top (Last In, First Out)
- ββββββ€
- β 20 β
- ββββββ€
- β 10 β
- ββββββ
+
+### Stack Operations
+
+```mermaid
+graph TD
+ subgraph "Push Operation"
+ P1["Stack: [10, 20]
Push(30)"] --> P2["1. Add 30 to top"]
+ P2 --> P3["Stack: [10, 20, 30]
β O(1) time"]
+ end
+
+ subgraph "Pop Operation"
+ Pop1["Stack: [10, 20, 30]
Pop()"] --> Pop2["1. Remove from top"]
+ Pop2 --> Pop3["Returns: 30
Stack: [10, 20]
β O(1) time"]
+ end
+
+ subgraph "Peek Operation"
+ Peek1["Stack: [10, 20, 30]
Peek()"] --> Peek2["1. View top element"]
+ Peek2 --> Peek3["Returns: 30
Stack unchanged
β O(1) time"]
+ end
+
+ style P3 fill:#90EE90
+ style Pop3 fill:#90EE90
+ style Peek3 fill:#90EE90
+```
+
+### Stack Use Cases Decision Tree
+
+```mermaid
+graph TD
+ Problem[Problem Type] --> Q1{Need to track
recent items?}
+
+ Q1 -->|Yes| Q2{Need reverse order
or undo?}
+ Q1 -->|Process nested| Q3{Matching pairs
or balanced?}
+
+ Q2 -->|Yes| Undo["β Use Stack
β’ Browser history
β’ Undo/Redo
β’ Function call stack"]
+
+ Q3 -->|Yes| Balanced["β Use Stack
β’ Valid parentheses
β’ HTML tag matching
β’ Expression evaluation"]
+
+ Q1 -->|Processing| Q4{Need to evaluate
expressions?}
+
+ Q4 -->|Yes| Eval["β Use Stack
β’ Infix to postfix
β’ Calculator
β’ Reverse Polish Notation"]
+
+ style Undo fill:#90EE90
+ style Balanced fill:#FFD700
+ style Eval fill:#87CEEB
```
## Key Operations
diff --git a/data-structures/trees.md b/data-structures/trees.md
index edbd82e..8ae7a50 100644
--- a/data-structures/trees.md
+++ b/data-structures/trees.md
@@ -4,31 +4,117 @@ A tree is a hierarchical data structure consisting of nodes connected by edges.
## Visual Representation
+### Binary Tree Structure
+
+```mermaid
+graph TD
+ Root[1
Root] --> L1_Left[2]
+ Root --> L1_Right[3]
+ L1_Left --> L2_LL[4]
+ L1_Left --> L2_LR[5]
+ L1_Right --> L2_RL[6]
+ L1_Right --> L2_RR[7]
+
+ style Root fill:#FFD700
+ style L1_Left fill:#87CEEB
+ style L1_Right fill:#87CEEB
+ style L2_LL fill:#90EE90
+ style L2_LR fill:#90EE90
+ style L2_RL fill:#90EE90
+ style L2_RR fill:#90EE90
```
-Binary Tree:
- βββββ
- β 1 β
- βββ¬ββ
- ββββββ΄βββββ
- ββββ΄βββ ββββ΄βββ
- β 2 β β 3 β
- ββββ¬βββ ββββ¬βββ
- ββββ΄βββ ββββ΄βββ
- β 4 β β 5 β
- βββββββ βββββββ
-
-Binary Search Tree (BST):
- βββββ
- β 8 β
- βββ¬ββ
- ββββββ΄βββββ
- ββββ΄βββ ββββ΄βββ
- β 3 β β 10 β
- ββββ¬βββ ββββ¬βββ
- ββββ΄βββ ββββ
- β 1 β ββββ΄βββ
- βββββββ β 14 β
- βββββββ
+
+### Binary Search Tree (BST) Structure
+
+BST Property: Left < Parent < Right
+
+```mermaid
+graph TD
+ Root[8
Root] --> L1_Left[3
Left < 8]
+ Root --> L1_Right[10
Right > 8]
+ L1_Left --> L2_LL[1
< 3]
+ L1_Left --> L2_LR[6
> 3, < 8]
+ L1_Right --> L2_RL[NULL]
+ L1_Right --> L2_RR[14
> 10]
+ L2_LR --> L3_LRL[4]
+ L2_LR --> L3_LRR[7]
+ L2_RR --> L3_RRL[13]
+ L2_RR --> L3_RRR[NULL]
+
+ style Root fill:#FFD700
+ style L1_Left fill:#87CEEB
+ style L1_Right fill:#87CEEB
+ style L2_LL fill:#90EE90
+ style L2_LR fill:#90EE90
+ style L2_RR fill:#90EE90
+ style L2_RL fill:#ffcccc
+ style L3_LRL fill:#98FB98
+ style L3_LRR fill:#98FB98
+ style L3_RRL fill:#98FB98
+ style L3_RRR fill:#ffcccc
+```
+
+### Tree Traversals Visualization
+
+```mermaid
+graph TD
+ subgraph "Tree Structure"
+ A[1] --> B[2]
+ A --> C[3]
+ B --> D[4]
+ B --> E[5]
+ C --> F[6]
+ C --> G[7]
+ end
+
+ subgraph "Traversal Orders"
+ Preorder["Preorder: Root β Left β Right
Result: 1, 2, 4, 5, 3, 6, 7
Use: Copy tree, prefix expression"]
+ Inorder["Inorder: Left β Root β Right
Result: 4, 2, 5, 1, 6, 3, 7
Use: BST sorted order"]
+ Postorder["Postorder: Left β Right β Root
Result: 4, 5, 2, 6, 7, 3, 1
Use: Delete tree, postfix expression"]
+ LevelOrder["Level Order: Level by level
Result: 1, 2, 3, 4, 5, 6, 7
Use: BFS, shortest path in tree"]
+ end
+
+ style Preorder fill:#FFE4B5
+ style Inorder fill:#E0FFE0
+ style Postorder fill:#E0E0FF
+ style LevelOrder fill:#FFE0F0
+```
+
+### BST Operations Decision Tree
+
+```mermaid
+graph TD
+ Start[BST Operation] --> Q1{What operation?}
+
+ Q1 -->|Search| Search[Compare with root]
+ Q1 -->|Insert| Insert[Find insertion point]
+ Q1 -->|Delete| Delete[Find node to delete]
+
+ Search --> SQ1{Target < Node?}
+ SQ1 -->|Yes| SLeft[Go left]
+ SQ1 -->|No| SQ2{Target > Node?}
+ SQ2 -->|Yes| SRight[Go right]
+ SQ2 -->|No| SFound[Found! Return node]
+
+ Insert --> IQ1{Value < Node?}
+ IQ1 -->|Yes| ILeft{Left is NULL?}
+ IQ1 -->|No| IRight{Right is NULL?}
+ ILeft -->|Yes| IInsertLeft[Insert as left child]
+ ILeft -->|No| IGoLeft[Go left, repeat]
+ IRight -->|Yes| IInsertRight[Insert as right child]
+ IRight -->|No| IGoRight[Go right, repeat]
+
+ Delete --> DQ1{Node has children?}
+ DQ1 -->|No children| D0[Remove node directly]
+ DQ1 -->|One child| D1[Replace with child]
+ DQ1 -->|Two children| D2["Find inorder successor
Replace value, delete successor"]
+
+ style SFound fill:#90EE90
+ style IInsertLeft fill:#90EE90
+ style IInsertRight fill:#90EE90
+ style D0 fill:#FFD700
+ style D1 fill:#FFD700
+ style D2 fill:#FFA500
```
## Types of Trees
diff --git a/data-structures/tries.md b/data-structures/tries.md
index 7bd1220..349bc20 100644
--- a/data-structures/tries.md
+++ b/data-structures/tries.md
@@ -38,6 +38,336 @@ Trie containing the words "cat", "car", "dog", "door":
4. **Prefix Search**: Find all words with a given prefix
5. **Autocomplete**: Suggest completions for a given prefix
+## How to Approach Trie Problems
+
+### Step 1: Identify if a Trie is Needed
+
+```mermaid
+graph TD
+ Start[Problem Analysis] --> Q1{Working with
strings/words?}
+
+ Q1 -->|No| Other[Not a trie problem]
+ Q1 -->|Yes| Q2{Need prefix-based
operations?}
+
+ Q2 -->|Yes| Trie1[β Use Trie]
+ Q2 -->|No| Q3{Need autocomplete
or suggestions?}
+
+ Q3 -->|Yes| Trie2[β Use Trie]
+ Q3 -->|No| Q4{Search for patterns
or word validation?}
+
+ Q4 -->|Yes| Q5{With wildcards?}
+ Q4 -->|No| Hash[Consider Hash Table]
+
+ Q5 -->|Yes| Trie3[β Use Trie
with backtracking]
+ Q5 -->|No| Q6{Multiple string
matching?}
+
+ Q6 -->|Yes| Trie4[β Use Trie]
+ Q6 -->|No| Simple[Simple string ops
may suffice]
+
+ style Trie1 fill:#90EE90
+ style Trie2 fill:#90EE90
+ style Trie3 fill:#87CEEB
+ style Trie4 fill:#90EE90
+ style Other fill:#FFB6C1
+ style Hash fill:#FFD700
+ style Simple fill:#DDA0DD
+```
+
+### Step 2: Common Trie Problem Patterns
+
+#### Pattern 1: Dictionary Operations
+
+```
+Problem indicators:
+- Add/remove words from dictionary
+- Check if word exists
+- Validate words
+
+Approach:
+1. Build trie with all dictionary words
+2. For search: traverse character by character
+3. Check end-of-word flag at final node
+
+Key operations:
+- Insert: O(m) where m = word length
+- Search: O(m)
+- Space: O(ALPHABET_SIZE * N * M) where N = number of words
+
+Template:
+class TrieNode:
+ def __init__(self):
+ self.children = {}
+ self.is_end = False
+
+trie = TrieNode()
+
+# Insert
+def insert(word):
+ node = trie
+ for char in word:
+ if char not in node.children:
+ node.children[char] = TrieNode()
+ node = node.children[char]
+ node.is_end = True
+
+# Search
+def search(word):
+ node = trie
+ for char in word:
+ if char not in node.children:
+ return False
+ node = node.children[char]
+ return node.is_end
+```
+
+#### Pattern 2: Prefix Matching & Autocomplete
+
+```
+Problem indicators:
+- Find all words with prefix
+- Autocomplete feature
+- Suggest words
+
+Approach:
+1. Navigate to prefix node
+2. DFS/BFS from prefix node
+3. Collect all words (nodes with is_end = True)
+
+Template:
+def get_words_with_prefix(prefix):
+ # Navigate to prefix node
+ node = trie
+ for char in prefix:
+ if char not in node.children:
+ return []
+ node = node.children[char]
+
+ # DFS to collect all words
+ result = []
+ def dfs(node, path):
+ if node.is_end:
+ result.append(prefix + path)
+ for char, child in node.children.items():
+ dfs(child, path + char)
+
+ dfs(node, "")
+ return result
+```
+
+#### Pattern 3: Word Search with Wildcards
+
+```
+Problem indicators:
+- Search with '.' matching any character
+- Pattern matching
+- Regex-like operations
+
+Approach:
+1. Use backtracking with trie
+2. For wildcard, try all children
+3. For regular char, follow specific path
+
+Template:
+def search_with_wildcard(word):
+ def dfs(node, i):
+ if i == len(word):
+ return node.is_end
+
+ char = word[i]
+ if char == '.':
+ # Try all children
+ for child in node.children.values():
+ if dfs(child, i + 1):
+ return True
+ return False
+ else:
+ # Follow specific path
+ if char not in node.children:
+ return False
+ return dfs(node.children[char], i + 1)
+
+ return dfs(trie, 0)
+```
+
+#### Pattern 4: Board/Grid Word Search
+
+```
+Problem indicators:
+- Find words in 2D grid
+- Words can be formed by adjacent cells
+- Multiple words to find
+
+Approach:
+1. Build trie with all target words
+2. DFS from each cell
+3. Prune search using trie
+4. Much faster than searching each word separately
+
+Template:
+def find_words(board, words):
+ # Build trie
+ trie = build_trie(words)
+ result = []
+ rows, cols = len(board), len(board[0])
+
+ def dfs(r, c, node, path):
+ if node.is_end:
+ result.append(path)
+ node.is_end = False # Avoid duplicates
+
+ if r < 0 or r >= rows or c < 0 or c >= cols:
+ return
+
+ char = board[r][c]
+ if char not in node.children:
+ return
+
+ board[r][c] = '#' # Mark visited
+
+ # Explore 4 directions
+ for dr, dc in [(0,1), (1,0), (0,-1), (-1,0)]:
+ dfs(r+dr, c+dc, node.children[char], path+char)
+
+ board[r][c] = char # Restore
+
+ for i in range(rows):
+ for j in range(cols):
+ dfs(i, j, trie, "")
+
+ return result
+```
+
+### Step 3: Trie vs. Other Data Structures
+
+```mermaid
+graph TD
+ Problem[String Problem] --> Op{Main Operation?}
+
+ Op -->|Exact match| Hash[Hash Table
O(1) lookup
No prefix support]
+ Op -->|Prefix operations| Compare{Compare features}
+ Op -->|Range queries| BST[Binary Search Tree
Sorted order]
+ Op -->|Pattern matching| Consider{Pattern type?}
+
+ Compare --> Space{Space constraint?}
+ Space -->|Critical| Hash2[Hash Table
Less space for
few words]
+ Space -->|Not critical| Trie[β Trie
Fast prefix ops
Autocomplete]
+
+ Consider -->|Wildcards| Trie2[β Trie with
backtracking]
+ Consider -->|Regex| Regex[Regex engine]
+
+ style Trie fill:#90EE90
+ style Trie2 fill:#90EE90
+ style Hash fill:#FFD700
+ style Hash2 fill:#FFD700
+ style BST fill:#87CEEB
+ style Regex fill:#DDA0DD
+```
+
+### Step 4: Problem-Solving Framework for Tries
+
+```
+STEP 1: Analyze the Problem
+β‘ Are we working with multiple strings/words?
+β‘ Do we need prefix-based operations?
+β‘ Is autocomplete/suggestion needed?
+β‘ Are there pattern matching requirements?
+
+STEP 2: Design the Trie Structure
+β‘ What does each node store?
+ - Children (dict/array)
+ - End-of-word flag
+ - Additional data (count, word itself, etc.)
+β‘ What's the alphabet size?
+ - Lowercase letters: 26
+ - All letters: 52
+ - Alphanumeric: 62
+ - Custom: varies
+
+STEP 3: Choose the Approach
+β‘ Simple trie: Basic insert/search/prefix
+β‘ Trie + DFS: Collect all words with prefix
+β‘ Trie + Backtracking: Pattern matching
+β‘ Trie + Grid DFS: Board word search
+
+STEP 4: Optimize
+β‘ Can we prune branches early?
+β‘ Do we need to store the full word at leaf nodes?
+β‘ Can we use array instead of dict for fixed alphabet?
+β‘ Should we compress the trie (suffix tree)?
+
+STEP 5: Implementation Checklist
+β‘ Handle empty strings
+β‘ Mark end-of-word correctly
+β‘ Don't forget to backtrack when needed
+β‘ Clean up/delete properly to avoid memory leaks
+```
+
+### Step 5: When to Use Trie vs Hash Table
+
+| Criteria | Use Trie | Use Hash Table |
+|----------|----------|---------------|
+| Prefix queries | β Excellent | β Not supported |
+| Autocomplete | β Natural fit | β Inefficient |
+| Exact lookup | O(m) | β O(1) average |
+| Space efficiency | Depends on overlap | β Better for few words |
+| Insert/Delete | O(m) | β O(1) average |
+| All words with prefix | β O(p + n) | β O(N) scan needed |
+| Sorted order | β DFS gives sorted | β Not ordered |
+| Pattern matching | β With backtracking | β No support |
+
+*m = word length, p = prefix length, n = results, N = total words*
+
+### Step 6: Common Mistakes to Avoid
+
+```
+1. NOT MARKING END OF WORD
+ β node.children['e'] exists doesn't mean "e" is a word
+ β Always check node.is_end flag
+
+2. MEMORY LEAKS ON DELETE
+ β Not removing empty nodes after delete
+ β Recursively delete unused nodes
+
+3. WRONG ALPHABET SIZE
+ β Using array of size 26 for mixed case strings
+ β Match data structure to input
+
+4. NOT HANDLING DUPLICATES
+ β Adding same word multiple times
+ β Check is_end or use count
+
+5. INEFFICIENT TRAVERSAL
+ β Recreating trie for each query
+ β Build once, query many times
+
+6. FORGETTING TO RESTORE STATE
+ β In grid problems, not unmarking cells
+ β Always backtrack properly
+```
+
+### Decision Matrix: Trie Problem Approach
+
+```mermaid
+graph TD
+ Start[Trie Problem] --> Q1{Number of
operations?}
+
+ Q1 -->|Few inserts,
many queries| Build[Build trie once
Query many times]
+ Q1 -->|Many inserts
and queries| Dynamic[Dynamic trie
Efficient insert/search]
+
+ Build --> Q2{Query type?}
+ Dynamic --> Q2
+
+ Q2 -->|Exact match| Simple[Simple trie
with is_end flag]
+ Q2 -->|Prefix match| DFS[Trie + DFS
to collect words]
+ Q2 -->|Pattern match| Back[Trie + Backtracking
for wildcards]
+ Q2 -->|In grid| Grid[Trie + Grid DFS
with pruning]
+
+ style Simple fill:#90EE90
+ style DFS fill:#87CEEB
+ style Back fill:#FFD700
+ style Grid fill:#DDA0DD
+```
+
## Implementation in Python and JavaScript
### Python
diff --git a/patterns/binary-search.md b/patterns/binary-search.md
index 55aa774..2032917 100644
--- a/patterns/binary-search.md
+++ b/patterns/binary-search.md
@@ -4,44 +4,77 @@ Binary Search is an efficient algorithm for finding an element in a sorted array
## Visual Representation
+### Binary Search Process
+
+```mermaid
+graph TD
+ Start["Array: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
Target: 13
Left=0, Right=9"] --> Step1
+ Step1["Step 1: Mid=4, arr[4]=9
9 < 13
Search RIGHT half"] --> Step2
+ Step2["Step 2: Left=5, Right=9
Mid=7, arr[7]=15
15 > 13
Search LEFT half"] --> Step3
+ Step3["Step 3: Left=5, Right=6
Mid=5, arr[5]=11
11 < 13
Search RIGHT half"] --> Step4
+ Step4["Step 4: Left=6, Right=6
Mid=6, arr[6]=13
13 == 13
β FOUND!"] --> Result["Return index 6"]
+
+ style Start fill:#e1f5ff
+ style Step1 fill:#FFE4B5
+ style Step2 fill:#FFD700
+ style Step3 fill:#FFA500
+ style Step4 fill:#90EE90
+ style Result fill:#90EE90
```
-Array: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
-Target: 13
-
-Step 1: Calculate mid = (0 + 9) / 2 = 4
- [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
- β
- mid = 9
- 9 < 13, so search in the right half
-
-Step 2: Calculate mid = (5 + 9) / 2 = 7
- [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
- β
- mid = 15
- 15 > 13, so search in the left half
-
-Step 3: Calculate mid = (5 + 6) / 2 = 5
- [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
- β
- mid = 11
- 11 < 13, so search in the right half
-
-Step 4: Calculate mid = (6 + 6) / 2 = 6
- [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
- β
- mid = 13
- 13 == 13, element found at index 6!
+
+### Binary Search Decision Flow
+
+```mermaid
+graph TD
+ Start[Binary Search] --> Init["Initialize:
left = 0
right = n-1"]
+ Init --> Loop{left β€ right?}
+
+ Loop -->|No| NotFound["Return -1
Element not found"]
+ Loop -->|Yes| CalcMid["mid = left + (right-left)/2"]
+
+ CalcMid --> Compare{arr[mid] vs target?}
+
+ Compare -->|Equal| Found["Return mid
Element found!"]
+ Compare -->|Less than| GoRight["left = mid + 1
Search right half"]
+ Compare -->|Greater than| GoLeft["right = mid - 1
Search left half"]
+
+ GoRight --> Loop
+ GoLeft --> Loop
+
+ style Found fill:#90EE90
+ style NotFound fill:#FFB6C6
```
## When to Use Binary Search
-- When the array is sorted
-- When you need to find a specific element or the insertion position of an element
-- When you need to find the first or last occurrence of an element
-- When you need to find the closest element to a target
-- When you need to search in a rotated sorted array
-- When you need to find a peak element
-- When you need to minimize the maximum or maximize the minimum value
+```mermaid
+graph TD
+ Problem[Problem Type] --> Q1{Is data sorted
or rotated sorted?}
+
+ Q1 -->|Yes| Q2{What are you
searching for?}
+ Q1 -->|No| NoBS["β Can't use Binary Search
Consider: Linear search,
Hash map, or sort first"]
+
+ Q2 -->|Exact element| Basic["β Basic Binary Search
O(log n)"]
+ Q2 -->|First/Last occurrence| FirstLast["β Modified Binary Search
Find boundary"]
+ Q2 -->|Insertion position| Insert["β Binary Search Variant
Return left pointer"]
+ Q2 -->|Peak element| Peak["β Binary Search
Compare with neighbors"]
+ Q2 -->|Rotated array| Rotated["β Modified Binary Search
Check which half is sorted"]
+ Q2 -->|Min/Max optimization| MinMax["β Binary Search on Answer
Search space reduction"]
+
+ style Basic fill:#90EE90
+ style FirstLast fill:#FFD700
+ style Insert fill:#87CEEB
+ style Peak fill:#FFB6C1
+ style Rotated fill:#DDA0DD
+ style MinMax fill:#F0E68C
+```
+
+**Key Indicators:**
+- Sorted or monotonic data
+- Keywords: "sorted array," "find element," "search"
+- Need O(log n) time complexity
+- "Minimum value to maximize" or "Maximum value to minimize" (binary search on answer)
+- Rotated sorted array problems
## Basic Binary Search Implementation
@@ -474,4 +507,204 @@ def binary_search(arr, target):
3. **Machine Learning**: Used in algorithms like binary decision trees.
4. **Computer Graphics**: Used in ray tracing and collision detection algorithms.
5. **Network Routing**: Used in routing algorithms to find the shortest path.
-6. **Game Development**: Used in pathfinding algorithms and AI decision-making.
\ No newline at end of file
+6. **Game Development**: Used in pathfinding algorithms and AI decision-making.
+
+## π‘ Tips and Tricks
+
+### Binary Search Variants Quick Reference
+
+```mermaid
+graph TD
+ Start[Binary Search Variants] --> V1[Find Exact Element]
+ Start --> V2[Find First Occurrence]
+ Start --> V3[Find Last Occurrence]
+ Start --> V4[Find Insert Position]
+
+ V1 --> V1C["Condition: arr[mid] == target
Return: mid
Update: Standard left/right"]
+
+ V2 --> V2C["Condition: arr[mid] >= target
Store result, search left
Return: stored result"]
+
+ V3 --> V3C["Condition: arr[mid] <= target
Store result, search right
Return: stored result"]
+
+ V4 --> V4C["Standard binary search
If not found, return left
left is insertion position"]
+
+ style V1C fill:#90EE90
+ style V2C fill:#FFD700
+ style V3C fill:#87CEEB
+ style V4C fill:#FFB6C1
+```
+
+### Pro Tips
+
+**1. Avoid Integer Overflow**
+```python
+# β Bad: Can overflow with large values
+mid = (left + right) // 2
+
+# β Good: Safe from overflow
+mid = left + (right - left) // 2
+```
+
+**2. Choose Correct Loop Condition**
+```python
+# Use left <= right for exact element search
+while left <= right: # Checks all elements including when left == right
+
+# Use left < right for finding boundaries
+while left < right: # Stops when left meets right
+```
+
+**3. Template for Finding First Occurrence**
+```python
+def find_first(arr, target):
+ left, right = 0, len(arr) - 1
+ result = -1
+
+ while left <= right:
+ mid = left + (right - left) // 2
+ if arr[mid] == target:
+ result = mid # Save result
+ right = mid - 1 # Continue searching left
+ elif arr[mid] < target:
+ left = mid + 1
+ else:
+ right = mid - 1
+
+ return result
+```
+
+**4. Template for Finding Last Occurrence**
+```python
+def find_last(arr, target):
+ left, right = 0, len(arr) - 1
+ result = -1
+
+ while left <= right:
+ mid = left + (right - left) // 2
+ if arr[mid] == target:
+ result = mid # Save result
+ left = mid + 1 # Continue searching right
+ elif arr[mid] < target:
+ left = mid + 1
+ else:
+ right = mid - 1
+
+ return result
+```
+
+**5. Binary Search on Answer (Advanced Pattern)**
+```python
+def binary_search_on_answer(arr, constraint):
+ # Define search space based on problem
+ left, right = min_possible, max_possible
+
+ while left < right:
+ mid = left + (right - left) // 2
+
+ # Check if mid satisfies the constraint
+ if is_feasible(mid, arr, constraint):
+ right = mid # Try smaller values (minimize)
+ else:
+ left = mid + 1
+
+ return left # Or right, they're equal
+```
+
+### Common Patterns Cheatsheet
+
+```mermaid
+graph TD
+ Patterns[Common Patterns] --> P1["Standard Search
while left β€ right
return mid or -1"]
+ Patterns --> P2["Find Boundary
while left < right
return left"]
+ Patterns --> P3["Rotated Array
Check which half sorted
Adjust search accordingly"]
+ Patterns --> P4["Search Answer Space
Binary search on range
Check feasibility"]
+
+ P1 --> P1E["Example:
Search for element"]
+ P2 --> P2E["Example:
First/last occurrence,
Insert position"]
+ P3 --> P3E["Example:
Search in rotated array,
Find pivot"]
+ P4 --> P4E["Example:
Split array largest sum,
Koko eating bananas"]
+
+ style P1 fill:#90EE90
+ style P2 fill:#FFD700
+ style P3 fill:#87CEEB
+ style P4 fill:#FFB6C1
+```
+
+### Debugging Checklist
+
+```mermaid
+graph TD
+ Debug[Binary Search Not Working?] --> D1{Infinite loop?}
+ Debug --> D2{Wrong answer?}
+ Debug --> D3{Array sorted?}
+
+ D1 -->|Yes| D1F["Fix: Ensure left or right
moves every iteration:
left = mid + 1
right = mid - 1"]
+
+ D2 -->|Yes| D2F["Check:
β’ Correct comparison?
β’ Handling duplicates?
β’ Return value correct?"]
+
+ D3 -->|No| D3F["Binary search requires
sorted data!
Sort first or use different approach"]
+
+ style D1F fill:#FFB6C6
+ style D2F fill:#FFE4B5
+ style D3F fill:#FFB6C6
+```
+
+### Interview Tips
+
+**1. Clarify Requirements**
+- Is array sorted? Ascending or descending?
+- Are there duplicates? Need first or last occurrence?
+- What to return if not found? -1? Insert position?
+
+**2. Choose Right Template**
+- Exact match β `left <= right`
+- Find boundary β `left < right`
+- Search answer space β `left < right` with feasibility check
+
+**3. Test Edge Cases**
+```python
+# Always test these:
+test_cases = [
+ [], # Empty array
+ [1], # Single element
+ [1, 1, 1], # All duplicates
+ [1, 2], # Two elements
+ [1, 2, 3, 4, 5], # No duplicates
+]
+```
+
+**4. Time & Space Complexity**
+- Time: O(log n) - Halving search space each iteration
+- Space: O(1) - Only using pointers
+- Recursive: O(log n) space for call stack
+
+### Common Mistakes to Avoid
+
+| Mistake | Problem | Solution |
+|---------|---------|----------|
+| `mid = (left + right) / 2` | Integer overflow | Use `left + (right-left)//2` |
+| Wrong loop condition | Missing elements or infinite loop | Match condition to problem type |
+| Not updating pointers | Infinite loop | Ensure `left` or `right` changes |
+| Comparing with wrong value | Wrong results | Double-check comparison logic |
+| Not handling edge cases | Crashes or wrong answers | Test empty, single element, duplicates |
+
+### Binary Search Complexity Guarantee
+
+```mermaid
+graph LR
+ Input[Array of size n] --> BS[Binary Search]
+ BS --> Steps["Maximum steps:
βlogβ(n)β + 1"]
+
+ Examples --> E1["n=10: 4 steps"]
+ Examples --> E2["n=100: 7 steps"]
+ Examples --> E3["n=1000: 10 steps"]
+ Examples --> E4["n=1,000,000: 20 steps"]
+
+ style BS fill:#90EE90
+ style Steps fill:#FFD700
+```
+
+**Why Binary Search is Powerful:**
+- Searches 1 billion elements in ~30 steps!
+- Each step eliminates half the remaining elements
+- Logarithmic growth means it scales incredibly well
\ No newline at end of file
diff --git a/patterns/fast-slow-pointers.md b/patterns/fast-slow-pointers.md
index e7d8f16..d19bdc8 100644
--- a/patterns/fast-slow-pointers.md
+++ b/patterns/fast-slow-pointers.md
@@ -4,30 +4,84 @@ The Fast & Slow Pointers pattern (also known as the Hare & Tortoise algorithm) u
## Visual Representation
+### Fast & Slow Pointer Movement
+
+```mermaid
+graph LR
+ subgraph "Iteration 1"
+ N1_1["1
S,F"] --> N2_1["2"] --> N3_1["3"] --> N4_1["4"] --> N5_1["5"]
+ end
+
+ subgraph "Iteration 2"
+ N1_2["1"] --> N2_2["2
S"] --> N3_2["3"] --> N4_2["4
F"] --> N5_2["5"]
+ end
+
+ subgraph "Iteration 3"
+ N1_3["1"] --> N2_3["2"] --> N3_3["3
S"] --> N4_3["4"] --> N5_3["5
F"]
+ end
+
+ style N1_1 fill:#FFD700
+ style N2_2 fill:#90EE90
+ style N4_2 fill:#87CEEB
+ style N3_3 fill:#90EE90
+ style N5_3 fill:#87CEEB
```
-Linked List with a cycle:
-
-1 β 2 β 3 β 4 β 5 β 6
- β β
- 9 β 8 β 7
-
-Initial state:
-1 β 2 β 3 β 4 β 5 β 6
-β β β
-S,F F β
- 9 β 8 β 7
-
-After some iterations:
-1 β 2 β 3 β 4 β 5 β 6
- β β β
- S F β
- 9 β 8 β 7
-
-Eventually:
-1 β 2 β 3 β 4 β 5 β 6
- β β
- S,F β
- 9 β 8 β 7
+
+### Cycle Detection Visual
+
+```mermaid
+graph TD
+ Start["Linked List: 1β2β3β4β5β3 (cycle)"] --> Init
+ Init["Initialize:
slow = head
fast = head"] --> Move1
+
+ Move1["Move pointers:
slow: 1β2
fast: 1β2β3"] --> Check1{slow == fast?}
+ Check1 -->|No| Move2
+
+ Move2["Move pointers:
slow: 2β3
fast: 3β4β5"] --> Check2{slow == fast?}
+ Check2 -->|No| Move3
+
+ Move3["Move pointers:
slow: 3β4
fast: 5β3β4"] --> Check3{slow == fast?}
+ Check3 -->|Yes| Cycle["β Cycle detected!
They met at node 4"]
+
+ NoCycleExample["No Cycle Example:
1β2β3β4βNULL"] --> NCInit["slow = head, fast = head"]
+ NCInit --> NCMove["fast reaches NULL
before meeting slow"]
+ NCMove --> NoCycle["β No cycle"]
+
+ style Cycle fill:#FFB6C6
+ style NoCycle fill:#90EE90
+```
+
+### Finding Middle Element
+
+```mermaid
+graph LR
+ subgraph "Find Middle of [1,2,3,4,5]"
+ Step1["slow=1, fast=1"] --> Step2["slow=2, fast=3"]
+ Step2 --> Step3["slow=3, fast=5"]
+ Step3 --> Result["fast at end
slow at middle: 3 β"]
+ end
+
+ style Result fill:#90EE90
+```
+
+### Pattern Decision Tree
+
+```mermaid
+graph TD
+ Problem[Linked List Problem] --> Q1{What to find?}
+
+ Q1 -->|Detect cycle| Cycle["Fast & Slow Pointers
Move until meet or NULL
O(n) time, O(1) space"]
+
+ Q1 -->|Find middle| Middle["Fast & Slow Pointers
Fast moves 2x speed
When fast ends, slow at middle"]
+
+ Q1 -->|Find kth from end| Kth["Two Pointers
Move fast k steps ahead
Then move both together"]
+
+ Q1 -->|Check palindrome| Palindrome["1. Find middle (fast/slow)
2. Reverse second half
3. Compare both halves"]
+
+ style Cycle fill:#FFD700
+ style Middle fill:#87CEEB
+ style Kth fill:#90EE90
+ style Palindrome fill:#FFB6C1
```
## When to Use Fast & Slow Pointers
diff --git a/patterns/merge-intervals.md b/patterns/merge-intervals.md
index 860f7ff..15ea824 100644
--- a/patterns/merge-intervals.md
+++ b/patterns/merge-intervals.md
@@ -4,27 +4,78 @@ The Merge Intervals pattern is a technique used to solve problems involving over
## Visual Representation
+### Merge Intervals Process
+
+```mermaid
+graph TD
+ Start["Intervals: [[1,3], [2,6], [8,10], [15,18]]"] --> Sort
+ Sort["Step 1: Sort by start time
[1,3], [2,6], [8,10], [15,18]
Already sorted β"] --> Merge1
+
+ Merge1["Step 2: Start with [1,3]
merged = [[1,3]]"] --> Check1
+ Check1["Check [2,6]:
2 β€ 3? YES β Overlap!
Merge: [1, max(3,6)] = [1,6]"] --> Check2
+
+ Check2["Check [8,10]:
8 β€ 6? NO β No overlap
Add separately"] --> Check3
+
+ Check3["Check [15,18]:
15 β€ 10? NO β No overlap
Add separately"] --> Result
+
+ Result["Final: [[1,6], [8,10], [15,18]]"]
+
+ style Start fill:#e1f5ff
+ style Sort fill:#FFE4B5
+ style Merge1 fill:#FFD700
+ style Check1 fill:#90EE90
+ style Result fill:#90EE90
```
-Intervals: [[1,3], [2,6], [8,10], [15,18]]
-
-Step 1: Sort intervals by start time
- [1,3], [2,6], [8,10], [15,18]
-
-Step 2: Merge overlapping intervals
- [1,3] and [2,6] overlap β [1,6]
- [1,6] and [8,10] don't overlap
- [8,10] and [15,18] don't overlap
-
-Result: [[1,6], [8,10], [15,18]]
+
+### Overlap Detection Visual
+
+```mermaid
+graph TD
+ subgraph "Overlapping Cases"
+ Case1["[1,5] and [3,7]
3 β€ 5? YES
Result: [1,7]"]
+ Case2["[1,5] and [2,4]
2 β€ 5? YES
Result: [1,5]"]
+ Case3["[1,5] and [5,7]
5 β€ 5? YES
Result: [1,7]"]
+ end
+
+ subgraph "Non-Overlapping Cases"
+ Case4["[1,3] and [4,6]
4 β€ 3? NO
Separate intervals"]
+ Case5["[1,3] and [5,7]
5 β€ 3? NO
Separate intervals"]
+ end
+
+ style Case1 fill:#90EE90
+ style Case2 fill:#90EE90
+ style Case3 fill:#90EE90
+ style Case4 fill:#FFB6C6
+ style Case5 fill:#FFB6C6
```
## When to Use Merge Intervals
-- When dealing with interval-based problems (time intervals, ranges, etc.)
-- When you need to find overlapping intervals
-- When you need to merge overlapping intervals
-- When you need to find gaps between intervals
-- When you need to check if an interval is free or conflicting with others
+```mermaid
+graph TD
+ Problem[Problem Type] --> Q1{Involves
intervals/ranges?}
+
+ Q1 -->|Yes| Q2{What operation?}
+ Q1 -->|No| NotInterval["Not an interval problem"]
+
+ Q2 -->|Merge overlaps| Merge["β Merge Intervals Pattern
Sort + merge overlapping"]
+ Q2 -->|Find conflicts| Conflict["β Check overlaps
Sort + detect conflicts"]
+ Q2 -->|Insert interval| Insert["β Insert & Merge
Find position + merge"]
+ Q2 -->|Find gaps| Gaps["β Find free slots
Sort + find gaps"]
+ Q2 -->|Count overlaps| Count["β Meeting rooms
Track concurrent intervals"]
+
+ style Merge fill:#90EE90
+ style Conflict fill:#FFD700
+ style Insert fill:#87CEEB
+ style Gaps fill:#FFB6C1
+ style Count fill:#DDA0DD
+```
+
+**Key Indicators:**
+- Time intervals, date ranges, number ranges
+- Keywords: "merge," "overlap," "conflict," "schedule," "meeting"
+- Need to combine or compare intervals
+- Find free time slots or available resources
## Common Problems and Solutions
@@ -473,4 +524,241 @@ def solve_interval_problem(intervals):
3. **Network Bandwidth Management**: Managing bandwidth allocation over time.
4. **Task Scheduling**: Scheduling tasks with start and end times.
5. **Flight Scheduling**: Managing flight schedules and gate assignments.
-6. **Hotel Booking Systems**: Managing room reservations and availability.
\ No newline at end of file
+6. **Hotel Booking Systems**: Managing room reservations and availability.
+
+## π‘ Tips and Tricks
+
+### Interval Pattern Decision Tree
+
+```mermaid
+graph TD
+ Start[Interval Problem] --> Q1{Need to
modify intervals?}
+
+ Q1 -->|Merge overlapping| Merge["Sort by start
Merge when overlap
O(n log n) time"]
+ Q1 -->|Insert one interval| Insert["Find position
Merge affected intervals
O(n) time"]
+ Q1 -->|Remove intervals| Remove["Sort by end time
Greedy selection
O(n log n) time"]
+
+ Q1 -->|Count something| Q2{What to count?}
+
+ Q2 -->|Maximum overlaps| MaxOverlap["Use sweep line
or min heap
Meeting Rooms II"]
+ Q2 -->|Minimum to remove| MinRemove["Sort by end
Greedy approach
Non-overlapping Intervals"]
+
+ style Merge fill:#90EE90
+ style Insert fill:#FFD700
+ style Remove fill:#87CEEB
+ style MaxOverlap fill:#FFB6C1
+ style MinRemove fill:#DDA0DD
+```
+
+### Pro Tips
+
+**1. Always Sort First**
+```python
+# β Essential first step for most interval problems
+intervals.sort(key=lambda x: x[0]) # Sort by start
+# OR
+intervals.sort(key=lambda x: x[1]) # Sort by end (for some problems)
+```
+
+**2. Overlap Condition**
+```python
+# Two intervals [a,b] and [c,d] overlap if:
+if c <= b: # c (start of second) <= b (end of first)
+ # They overlap!
+
+# Merge them:
+merged = [a, max(b, d)]
+```
+
+**3. Common Patterns**
+```python
+# Pattern 1: Merge all overlapping
+def merge(intervals):
+ intervals.sort(key=lambda x: x[0])
+ merged = [intervals[0]]
+ for curr in intervals[1:]:
+ if curr[0] <= merged[-1][1]:
+ merged[-1][1] = max(merged[-1][1], curr[1])
+ else:
+ merged.append(curr)
+ return merged
+
+# Pattern 2: Count maximum overlaps (Meeting Rooms II)
+def min_meeting_rooms(intervals):
+ starts = sorted([i[0] for i in intervals])
+ ends = sorted([i[1] for i in intervals])
+ rooms = max_rooms = 0
+ s = e = 0
+
+ while s < len(starts):
+ if starts[s] < ends[e]:
+ rooms += 1
+ max_rooms = max(max_rooms, rooms)
+ s += 1
+ else:
+ rooms -= 1
+ e += 1
+ return max_rooms
+```
+
+**4. Interval Representation**
+```python
+# Use consistent representation
+[start, end] # Most common
+# OR
+(start, end) # Tuple (immutable)
+# OR
+class Interval:
+ def __init__(self, start, end):
+ self.start = start
+ self.end = end
+```
+
+### Common Patterns Cheatsheet
+
+```mermaid
+graph TD
+ Patterns[Interval Patterns] --> P1["Merge Overlapping
Sort by start
Merge when curr.start β€ prev.end"]
+ Patterns --> P2["Insert Interval
3 phases: before, overlap, after
Merge overlapping ones"]
+ Patterns --> P3["Non-overlapping
Sort by end
Greedy: keep earliest ending"]
+ Patterns --> P4["Max Concurrent
Sweep line algorithm
Track starts and ends"]
+
+ P1 --> P1E["Example:
Merge Intervals"]
+ P2 --> P2E["Example:
Insert Interval"]
+ P3 --> P3E["Example:
Minimum removals,
Burst balloons"]
+ P4 --> P4E["Example:
Meeting Rooms II,
Max CPU load"]
+
+ style P1 fill:#90EE90
+ style P2 fill:#FFD700
+ style P3 fill:#87CEEB
+ style P4 fill:#FFB6C1
+```
+
+### Debugging Checklist
+
+```mermaid
+graph TD
+ Debug[Interval Problem Not Working?] --> D1{Sorted correctly?}
+ Debug --> D2{Overlap condition right?}
+ Debug --> D3{Edge cases handled?}
+
+ D1 -->|No| D1F["Fix: Sort by start
intervals.sort(key=lambda x: x[0])
or by end for some problems"]
+
+ D2 -->|No| D2F["Check overlap condition:
curr[0] β€ prev[1]
NOT curr[0] < prev[1]"]
+
+ D3 -->|No| D3F["Check:
β’ Empty intervals list
β’ Single interval
β’ All overlapping
β’ None overlapping"]
+
+ style D1F fill:#FFB6C6
+ style D2F fill:#FFB6C6
+ style D3F fill:#FFE4B5
+```
+
+### Problem-Specific Tricks
+
+**For Merge Intervals:**
+- Always sort by start time first
+- Use `max()` when updating end time
+- Can modify in-place or use new array
+
+**For Meeting Rooms II:**
+- Two-pointer technique on sorted starts and ends
+- Or use min heap to track ongoing meetings
+- Count peaks in overlap graph
+
+**For Non-overlapping Intervals:**
+- Sort by end time (greedy)
+- Keep interval with earliest end
+- Count how many we keep, return total - kept
+
+**For Insert Interval:**
+- Three phases: before insertion, during overlap, after insertion
+- Merge all overlapping intervals in middle phase
+
+### Complexity Analysis
+
+```mermaid
+graph LR
+ Input[Intervals: n intervals] --> Sort[Sort: O n log n]
+ Sort --> Scan[Scan: O n]
+ Scan --> Total["Total: O(n log n)
Dominated by sorting"]
+
+ Space[Space Complexity] --> S1["O(n) for result
or O(1) if modifying in-place"]
+
+ style Total fill:#90EE90
+ style S1 fill:#FFD700
+```
+
+**Time Complexity: O(n log n)**
+- Sorting: O(n log n)
+- Scanning: O(n)
+- Total dominated by sorting
+
+**Space Complexity:**
+- O(n) for result array
+- O(1) extra space (not counting result)
+- Sorting may use O(log n) stack space
+
+### Interview Tips
+
+**1. Clarify Interval Representation**
+- Inclusive or exclusive endpoints?
+- `[1,3]` means 1 and 3 included or 1 included, 3 excluded?
+- Can intervals have same start/end?
+
+**2. Ask About Edge Cases**
+- Empty list of intervals?
+- Single interval?
+- All intervals identical?
+- Intervals already sorted?
+
+**3. Common Interview Mistakes**
+
+| Mistake | Problem | Fix |
+|---------|---------|-----|
+| Wrong overlap check | `curr[0] < prev[1]` | Use `curr[0] <= prev[1]` |
+| Not sorting | Incorrect results | Always sort by start (or end) first |
+| Wrong end time | Not taking maximum | Use `max(prev[1], curr[1])` |
+| Modifying while iterating | Index errors | Use new array or careful indexing |
+| Not handling single interval | Edge case failure | Check `if len(intervals) <= 1` |
+
+**4. Template to Remember**
+```python
+def interval_problem(intervals):
+ if not intervals:
+ return []
+
+ # Sort by start (or end, depending on problem)
+ intervals.sort(key=lambda x: x[0])
+
+ result = [intervals[0]] # or appropriate initialization
+
+ for curr in intervals[1:]:
+ prev = result[-1]
+
+ # Check overlap
+ if curr[0] <= prev[1]:
+ # Merge: update prev's end
+ prev[1] = max(prev[1], curr[1])
+ else:
+ # No overlap: add curr
+ result.append(curr)
+
+ return result
+```
+
+### Visual Debugging Tips
+
+When debugging interval problems, draw them:
+```
+Timeline visualization:
+[1,3] [8,10] [15,18]
+|--| |--| |---|
+[2,6]
+ |----|
+
+After merge:
+[1,6] [8,10] [15,18]
+|-----| |--| |---|
+```
+
+This helps visualize overlaps and gaps!
\ No newline at end of file
diff --git a/patterns/sliding-window.md b/patterns/sliding-window.md
index afb61be..884abe8 100644
--- a/patterns/sliding-window.md
+++ b/patterns/sliding-window.md
@@ -4,23 +4,64 @@ The Sliding Window pattern is a technique used to process arrays or lists in a s
## Visual Representation
+### Fixed-Size Sliding Window
+
+```mermaid
+graph TD
+ subgraph "Array: [2, 6, 4, 8, 10, 9, 15], Window Size: 3"
+ Step1["Step 1: [2, 6, 4] = 12
Left=0, Right=2"] --> Step2
+ Step2["Step 2: [6, 4, 8] = 18
Left=1, Right=3
Remove 2, Add 8"] --> Step3
+ Step3["Step 3: [4, 8, 10] = 22
Left=2, Right=4
Remove 6, Add 10"] --> Step4
+ Step4["Step 4: [8, 10, 9] = 27
Left=3, Right=5
Remove 4, Add 9"] --> Step5
+ Step5["Step 5: [10, 9, 15] = 34 β MAX
Left=4, Right=6
Remove 8, Add 15"]
+ end
+
+ style Step5 fill:#90EE90
```
-Array: [2, 6, 4, 8, 10, 9, 15]
-Window size: 3
-
-Iteration 1: [2, 6, 4], 8, 10, 9, 15
-Iteration 2: 2, [6, 4, 8], 10, 9, 15
-Iteration 3: 2, 6, [4, 8, 10], 9, 15
-Iteration 4: 2, 6, 4, [8, 10, 9], 15
-Iteration 5: 2, 6, 4, 8, [10, 9, 15]
+
+### Dynamic-Size Sliding Window
+
+```mermaid
+graph TD
+ subgraph "Find Longest Substring Without Repeating: 'abcabcbb'"
+ S1["Window: 'a'
Left=0, Right=0, Max=1"] --> S2
+ S2["Window: 'ab'
Left=0, Right=1, Max=2"] --> S3
+ S3["Window: 'abc'
Left=0, Right=2, Max=3 β"] --> S4
+ S4["'a' repeats!
Shrink: Left=1, Right=3
Window: 'bca'"] --> S5
+ S5["'b' repeats!
Shrink: Left=2, Right=4
Window: 'cab'"] --> Continue["Continue..."]
+ end
+
+ style S3 fill:#90EE90
```
## When to Use Sliding Window
-- When dealing with contiguous sequences of elements in arrays, strings, or linked lists
-- When you need to find a subarray or substring that meets certain conditions
-- When you need to calculate something among all subarrays or substrings of a specific size
-- When the problem involves finding the maximum, minimum, or optimal value of something in a subarray or substring
+```mermaid
+graph TD
+ Start[Problem Analysis] --> Q1{Contiguous
sequence needed?}
+
+ Q1 -->|Yes| Q2{Fixed size
or variable?}
+ Q1 -->|No| NotSW[Not Sliding Window]
+
+ Q2 -->|Fixed size K| Fixed["Fixed Window
- Max/min sum of K elements
- Average of K elements
- K-size subarray problems"]
+
+ Q2 -->|Variable size| Q3{What constraint?}
+
+ Q3 -->|Sum/Product| Dynamic1["Dynamic Window
- Subarray with sum = target
- Smallest subarray with sum β₯ target"]
+ Q3 -->|Unique elements| Dynamic2["Dynamic Window
- Longest substring without repeats
- Longest substring with K distinct chars"]
+ Q3 -->|Character count| Dynamic3["Dynamic Window
- Longest substring with at most K chars
- Minimum window substring"]
+
+ style Fixed fill:#87CEEB
+ style Dynamic1 fill:#90EE90
+ style Dynamic2 fill:#FFD700
+ style Dynamic3 fill:#FFB6C1
+```
+
+**Key Indicators:**
+- Contiguous sequences (subarrays, substrings)
+- Find maximum, minimum, or optimal value
+- Calculate something among all subarrays of specific size
+- "Longest," "shortest," "maximum," "minimum" keywords
## Types of Sliding Windows
@@ -28,10 +69,48 @@ Iteration 5: 2, 6, 4, 8, [10, 9, 15]
The window size remains constant throughout the algorithm.
+**Pattern Template:**
+```python
+def fixed_window(arr, k):
+ # Initialize window
+ window_value = initial_calculation(arr[:k])
+ result = window_value
+
+ # Slide window
+ for i in range(k, len(arr)):
+ # Remove left element, add right element
+ window_value = window_value - arr[i-k] + arr[i]
+ result = update_result(result, window_value)
+
+ return result
+```
+
### 2. Dynamic-Size Window
The window size can grow or shrink based on certain conditions.
+**Pattern Template:**
+```python
+def dynamic_window(arr, condition):
+ left = 0
+ window_state = initial_state()
+ result = initial_result()
+
+ for right in range(len(arr)):
+ # Expand window
+ add_to_window(arr[right], window_state)
+
+ # Shrink window while condition violated
+ while not condition_met(window_state):
+ remove_from_window(arr[left], window_state)
+ left += 1
+
+ # Update result
+ result = update_result(result, window_state)
+
+ return result
+```
+
## Common Problems and Solutions
### 1. Maximum Sum Subarray of Size K (Fixed Window)
@@ -502,4 +581,133 @@ def sliding_window(arr):
3. **Image Processing**: Applying filters or convolutions to images using a sliding window.
4. **Natural Language Processing**: Analyzing text using n-grams or other sliding window techniques.
5. **Anomaly Detection**: Detecting anomalies in time series data using a sliding window approach.
-6. **Rate Limiting**: Implementing rate limiting algorithms using a sliding window to track requests over time.
\ No newline at end of file
+6. **Rate Limiting**: Implementing rate limiting algorithms using a sliding window to track requests over time.
+
+## π‘ Tips and Tricks
+
+### Quick Decision Matrix
+
+```mermaid
+graph LR
+ Start[Sliding Window Problem] --> Q1{Know window size?}
+
+ Q1 -->|Yes, size K| Tip1["β Use Fixed Window
β’ Calculate first window
β’ Slide: remove left, add right
β’ O(n) time, O(1) space"]
+
+ Q1 -->|No, find optimal| Q2{What to track?}
+
+ Q2 -->|Sum/Count| Tip2["β Use HashMap + Counters
β’ Track frequencies
β’ Expand until invalid
β’ Shrink while invalid"]
+
+ Q2 -->|Characters| Tip3["β Use Set/Map
β’ Track unique elements
β’ Use set for uniqueness
β’ Use map for frequencies"]
+
+ style Tip1 fill:#90EE90
+ style Tip2 fill:#FFD700
+ style Tip3 fill:#87CEEB
+```
+
+### Pro Tips
+
+**1. Always Think Incremental**
+```python
+# β Bad: Recalculating entire window
+window_sum = sum(arr[left:right+1])
+
+# β Good: Incremental update
+window_sum = window_sum - arr[left] + arr[right]
+```
+
+**2. Use Hash Maps for Character/Element Tracking**
+```python
+# Track frequencies for anagram problems
+char_count = {} # or defaultdict(int)
+char_count[char] = char_count.get(char, 0) + 1
+```
+
+**3. Two Conditions for Window Validity**
+- **Expand condition**: When can we add to window?
+- **Shrink condition**: When must we remove from window?
+
+**4. Track Both Current and Best**
+```python
+max_length = 0 # Best seen so far
+current_length = right - left + 1 # Current window
+max_length = max(max_length, current_length)
+```
+
+**5. Handle Edge Cases First**
+```python
+if not arr or k <= 0:
+ return [] # or appropriate default
+```
+
+### Common Mistakes to Avoid
+
+```mermaid
+graph TD
+ Mistakes[Common Mistakes] --> M1[Off-by-One Errors]
+ Mistakes --> M2[Forgetting to Update Result]
+ Mistakes --> M3[Not Shrinking Window]
+ Mistakes --> M4[Wrong Window Size Calculation]
+
+ M1 --> M1Fix["Fix: Use 'right - left + 1'
for window size, not 'right - left'"]
+ M2 --> M2Fix["Fix: Update result after
every window adjustment"]
+ M3 --> M3Fix["Fix: Use 'while' loop
for shrinking, not 'if'"]
+ M4 --> M4Fix["Fix: Check condition:
window_end >= k - 1"]
+
+ style M1Fix fill:#90EE90
+ style M2Fix fill:#90EE90
+ style M3Fix fill:#90EE90
+ style M4Fix fill:#90EE90
+```
+
+### Problem-Specific Tricks
+
+**For "Longest" Problems:**
+- Use maximum to track best result
+- Expand aggressively, shrink minimally
+- Often use sets or maps to track uniqueness
+
+**For "Shortest" Problems:**
+- Use minimum to track best result
+- Shrink aggressively once condition met
+- Often involves sum or count thresholds
+
+**For "All Subarrays" Problems:**
+- May need to check at every position
+- Result often accumulates counts
+- Consider number of valid windows ending at each position
+
+### Performance Optimization
+
+```mermaid
+graph TD
+ Opt[Optimization Tips] --> O1["Use appropriate data structures"]
+ Opt --> O2["Avoid nested loops in window"]
+ Opt --> O3["Update incrementally"]
+
+ O1 --> O1D["β’ Set for O(1) lookup
β’ Array for fixed size
β’ HashMap for frequencies"]
+ O2 --> O2D["β’ Each element processed once
β’ O(n) overall complexity"]
+ O3 --> O3D["β’ Add/remove one element
β’ Don't recalculate entire window"]
+
+ style O1D fill:#E0FFE0
+ style O2D fill:#FFE0E0
+ style O3D fill:#E0F5FF
+```
+
+### Complexity Analysis Rules
+
+- **Time Complexity**: O(n) where n = array/string length
+ - Each element added once, removed once
+ - Even with while loop for shrinking, total O(2n) = O(n)
+
+- **Space Complexity**:
+ - Fixed window: O(1)
+ - Dynamic with char tracking: O(k) where k = unique characters
+ - With all elements: O(n) worst case
+
+### Interview Tips
+
+1. **Clarify the problem**: Fixed or dynamic window?
+2. **Identify the condition**: What makes a window valid/invalid?
+3. **Choose data structure**: Array sum? Use variable. Characters? Use HashMap.
+4. **Code the template**: Start with expand, add shrink if needed
+5. **Test edge cases**: Empty input, single element, all same elements
\ No newline at end of file
diff --git a/patterns/two-pointers.md b/patterns/two-pointers.md
index 47a6f2b..c28dd5d 100644
--- a/patterns/two-pointers.md
+++ b/patterns/two-pointers.md
@@ -21,63 +21,103 @@ The Two Pointers pattern uses two pointers to iterate through a data structure i
## Types of Two Pointers Approaches
+### Two Pointers Strategy Selector
+
+```mermaid
+graph TD
+ Start[Two Pointers Problem] --> Q1{Array/List sorted?}
+
+ Q1 -->|Yes| Q2{Looking for pairs
or triplets?}
+ Q1 -->|No| Q3{Need to compare
or validate?}
+
+ Q2 -->|Yes| Opposite["Opposite Direction
Left β β Right
Use: Two Sum, 3Sum, Container with Water"]
+ Q2 -->|No| Q4{Need to find
cycle or middle?}
+
+ Q4 -->|Yes| FastSlow["Fast & Slow Pointers
Slow: +1, Fast: +2
Use: Cycle detection, Find middle"]
+ Q4 -->|No| Window["Sliding Window
Both move right
Use: Subarrays, Substrings"]
+
+ Q3 -->|Palindrome| Expand["Expand from Center
Left β β Right
Use: Palindrome validation"]
+ Q3 -->|Remove duplicates| Same["Same Direction
slow, fast both β
Use: Remove duplicates in-place"]
+
+ style Opposite fill:#87CEEB
+ style FastSlow fill:#FFD700
+ style Window fill:#90EE90
+ style Expand fill:#FFB6C1
+ style Same fill:#DDA0DD
+```
+
### 1. Opposite Direction (Left and Right)
Start with one pointer at the beginning and one at the end, then move them toward each other.
-**Visual Representation:**
-```
-Array: [1, 2, 3, 4, 5, 6, 7, 8]
-Initial state:
-β β
-[1, 2, 3, 4, 5, 6, 7, 8]
-left right
-
-After some iterations:
- β β
-[1, 2, 3, 4, 5, 6, 7, 8]
- left right
+```mermaid
+graph TD
+ subgraph "Two Sum in Sorted Array"
+ Start["Array: [1, 2, 3, 4, 6, 8]
Target: 10
Left=0, Right=5"] --> Step1
+ Step1["arr[L] + arr[R] = 1 + 8 = 9
9 < 10, move Leftβ"] --> Step2
+ Step2["L=1, R=5
arr[L] + arr[R] = 2 + 8 = 10
Found! Return [1, 5]"] --> Result["β Solution: indices [1, 5]"]
+ end
+
+ style Start fill:#e1f5ff
+ style Step1 fill:#FFE4B5
+ style Step2 fill:#FFD700
+ style Result fill:#90EE90
```
### 2. Same Direction (Fast and Slow)
Both pointers start from the beginning but move at different speeds.
-**Visual Representation:**
-```
-Array: [1, 2, 3, 4, 5, 6, 7, 8]
-Initial state:
-β
-[1, 2, 3, 4, 5, 6, 7, 8]
-slow
-fast
-
-After some iterations:
- β β
-[1, 2, 3, 4, 5, 6, 7, 8]
- slow fast
+```mermaid
+graph TD
+ subgraph "Remove Duplicates from Sorted Array"
+ Init["Array: [1, 1, 2, 2, 3, 4, 4]
Slow=0, Fast=1"] --> I1
+ I1["Fast=1: arr[1]=1 duplicate
Move Fastβ"] --> I2
+ I2["Fast=2: arr[2]=2 new!
Slow++, arr[Slow]=arr[Fast]
Array: [1, 2, 2, 2, 3, 4, 4]"] --> I3
+ I3["Continue...
Result: [1, 2, 3, 4, ...]
Return Slow+1 = 4"] --> Res["β Length of unique = 4"]
+ end
+
+ style Init fill:#e1f5ff
+ style I1 fill:#FFE4B5
+ style I2 fill:#FFD700
+ style I3 fill:#FFA500
+ style Res fill:#90EE90
```
-### 3. Sliding Window (Special Case)
+### 3. Fast and Slow Pointers (Cycle Detection)
+
+```mermaid
+graph LR
+ Start["Linked List with Cycle"] --> Algo["Floyd's Algorithm
Slow: +1 step
Fast: +2 steps"]
-A variation where both pointers move in the same direction, maintaining a "window" between them.
+ Algo --> Meet{Do they meet?}
+
+ Meet -->|No, FastβNULL| NoCycle["No cycle detected"]
+ Meet -->|Yes, meet at node| HasCycle["Cycle detected!
Continue to find cycle start"]
+
+ style Start fill:#e1f5ff
+ style Algo fill:#FFD700
+ style NoCycle fill:#FFB6C6
+ style HasCycle fill:#90EE90
+```
-**Visual Representation:**
+### 4. Sliding Window (Special Case)
+
+```mermaid
+graph TD
+ subgraph "Longest Substring Without Repeating Characters"
+ S1["String: 'abcabcbb'
Left=0, Right=0, MaxLen=0"] --> S2
+ S2["Expand: Right moves
Window: 'abc', MaxLen=3"] --> S3
+ S3["Right=3: 'a' duplicate!
Shrink: Left moves
Remove duplicates"] --> S4
+ S4["Continue expanding...
Final MaxLen=3"] --> SR["β Answer: 3"]
+ end
+
+ style S1 fill:#e1f5ff
+ style S2 fill:#FFD700
+ style S3 fill:#FFA500
+ style S4 fill:#90EE90
+ style SR fill:#90EE90
```
-Array: [1, 2, 3, 4, 5, 6, 7, 8]
-Initial state:
-β β
-[1, 2, 3, 4, 5, 6, 7, 8]
-L R
-
-After expanding window:
-β β
-[1, 2, 3, 4, 5, 6, 7, 8]
-L R
-
-After sliding window:
- β β
-[1, 2, 3, 4, 5, 6, 7, 8]
L R
```