├── README.md ├── bst ├── README.md ├── index.js └── task.md ├── deque ├── README.md ├── index.js └── task.md ├── graph ├── README.md ├── index.js └── task.md ├── hash_table ├── README.md ├── index.js └── task.md ├── heap ├── README.md ├── index.js └── task.md ├── linked_list ├── README.md ├── index.js └── task.md ├── priority_queue ├── README.md ├── index.js └── task.md ├── queue ├── README.md ├── index.js ├── task.js └── task.md ├── set ├── README.md ├── index.js └── task.md ├── stack ├── README.md ├── index.js ├── task.js └── task.md └── trie ├── README.md ├── index.js └── task.md /README.md: -------------------------------------------------------------------------------- 1 | # Data Structures Tutorial Series 🚀 2 | 3 | Welcome to our comprehensive **Data Structures Tutorial**! Whether you're a beginner or have some programming experience, this tutorial series will explain key data structures in a way that's easy to understand for all levels. We’ll cover the following data structures using both **text-based explanations** and **video tutorials**, so everyone can learn in the format that suits them best. 4 | 5 | ## Optimized Learning Plan for Data Structures 6 | 7 | This learning plan is designed to teach you the key data structures in **12 days**. Each day focuses on a single data structure, keeping lessons under **1 hour**. The plan is broken down into three sections: 8 | 1. **Introduction to the Data Structure** (5 minutes) 9 | 2. **Class Implementation** (10 minutes) 10 | 3. **Task/Problem Solving & Interview Practice** (10 minutes) 11 | 4. **Home Task** (10 minutes) 12 | 13 | By following this structure, you'll quickly grasp each concept, implement it, and practice with real-world tasks and interview-style problems. 14 | 15 | --- 16 | 17 | ### Day 1: Queue (FIFO - First In, First Out) [Lesson](https://github.com/fix2015/structure_tutorial/tree/main/queue/README.md) 18 | - **0-5 minutes**: Check the Home Task. 19 | - **5-10 minutes**: Introduction to Queue and its key operations: `enqueue(item)`, `dequeue()`, `peek()`, `isEmpty()`. 20 | - **10-20 minutes**: Implement a Queue class from scratch. 21 | - **20-30 minutes**: Task - Build a task scheduler using Queue (Interview problem). 22 | - **30-40 minutes**: Home Task [Task](https://github.com/fix2015/structure_tutorial/tree/main/queue/task.md). 23 | - **Video Tutorial**: [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7461216459239247136) (3m 37s). 24 | - **Queue structure example - Customer Support System** [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7466927598119996704) 25 | - **Queue structure example - Task Scheduler for Background Jobs** [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7466929364978961697) 26 | - [Github](https://github.com/fix2015/structure_queue) 27 | 28 | --- 29 | 30 | ### Day 2: Stack (LIFO - Last In, First Out) [Lesson](https://github.com/fix2015/structure_tutorial/tree/main/stack/README.md) 31 | - **0-5 minutes**: Check the Home Task from Day 1 (Review solutions and discuss any issues). 32 | - **5-10 minutes**: Introduction to Stack and its key operations: `push(item)`, `pop()`, `peek()`, `isEmpty()`. 33 | - **10-20 minutes**: Implement a Stack class from scratch. 34 | - **20-30 minutes**: Task - Implement undo functionality using Stack (Interview problem). 35 | - **30-40 minutes**: Home Task [Task](https://github.com/fix2015/structure_tutorial/tree/main/stack/task.md). 36 | - **Video Tutorial**: [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7461216459239247136) (5m 16s). 37 | - **Stack data structure example - Web browser history**: [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7466931370267299104) 38 | - **Stack data structure example - Web browser history**: [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7466931370267299104) 39 | - [Github](https://github.com/fix2015/structure_stack) 40 | 41 | --- 42 | 43 | ### Day 3: Linked List [Lesson](https://github.com/fix2015/structure_tutorial/tree/main/linked_list/README.md) 44 | - **0-5 minutes**: Check the Home Task from Day 2 (Review solutions and discuss any issues). 45 | - **5-10 minutes**: Introduction to Linked List, nodes, and pointers. 46 | - **10-20 minutes**: Implement a Singly Linked List class from scratch. 47 | - **20-30 minutes**: Task - Build a Playlist Management System using Linked List (Interview problem). 48 | - **30-40 minutes**: Home Task [Task](https://github.com/fix2015/structure_tutorial/tree/main/linked_list/task.md). 49 | - **Video Tutorial**: [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7461629272965319969). 50 | - **Linked list example - todo list** [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7466932230309383456) 51 | - **Linked list example - Browser tabs** [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7466933609023163680) 52 | - **Linked list example - Music player** [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7466934266048302369) 53 | - **Hash table example - User database facebook** [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7466935759832993057) 54 | - [Github](https://github.com/fix2015/structure_linked_list) 55 | 56 | --- 57 | 58 | ### Day 4: Hash Table [Lesson](https://github.com/fix2015/structure_tutorial/tree/main/hash_table/README.md) 59 | - **0-5 minutes**: Check the Home Task from Day 3 (Review solutions and discuss any issues). 60 | - **5-10 minutes**: Introduction to Hash Table, hash functions, and collision handling. 61 | - **10-20 minutes**: Implement a Hash Table class from scratch. 62 | - **20-30 minutes**: Task - Implement a simple caching system using Hash Table (Interview problem). 63 | - **30-40 minutes**: Home Task [Task](https://github.com/fix2015/structure_tutorial/tree/main/hash_table/task.md). 64 | - **Video Tutorial**: [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7461633571938258208). 65 | - **Hash table example - Word frequency** [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7466935005650963744) 66 | - [Github](https://github.com/fix2015/hash_table) 67 | 68 | --- 69 | 70 | ### Day 5: Binary Search Tree (BST) [Lesson](https://github.com/fix2015/structure_tutorial/tree/main/bst/README.md) 71 | - **0-5 minutes**: Check the Home Task from Day 4 (Review solutions and discuss any issues). 72 | - **5-10 minutes**: Introduction to BST and its properties. 73 | - **10-20 minutes**: Implement a BST class from scratch. 74 | - **20-30 minutes**: Task - Implement a simple search system using BST (Interview problem). 75 | - **30-40 minutes**: Home Task [Task](https://github.com/fix2015/structure_tutorial/tree/main/bst/task.md). 76 | - **Video Tutorial**: [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7461637491943116065). 77 | - [Github](https://github.com/fix2015/structure_bst) 78 | 79 | --- 80 | 81 | ### Day 6: Graph [Lesson](https://github.com/fix2015/structure_tutorial/tree/main/graph/README.md) 82 | - **0-5 minutes**: Check the Home Task from Day 5 (Review solutions and discuss any issues). 83 | - **5-10 minutes**: Introduction to Graph, types (directed, undirected), and graph traversal. 84 | - **10-20 minutes**: Implement a Graph class from scratch. 85 | - **20-30 minutes**: Task - Build a Social Network using Graph (Interview problem). 86 | - **30-40 minutes**: Home Task [Task](https://github.com/fix2015/structure_tutorial/tree/main/graph/task.md). 87 | - **Video Tutorial**: [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7461640836569140513). 88 | - [Github](https://github.com/fix2015/structure_graph) 89 | 90 | --- 91 | 92 | ### Day 7: Priority Queue [Lesson](https://github.com/fix2015/structure_tutorial/tree/main/priority_queue/README.md) 93 | - **0-5 minutes**: Check the Home Task from Day 6 (Review solutions and discuss any issues). 94 | - **5-10 minutes**: Introduction to Priority Queue and its operations. 95 | - **10-20 minutes**: Implement a Priority Queue class from scratch. 96 | - **20-30 minutes**: Task - Build a Task Scheduler using Priority Queue (Interview problem). 97 | - **30-40 minutes**: Home Task [Task](https://github.com/fix2015/structure_tutorial/tree/main/priority_queue/task.md). 98 | - **Video Tutorial**: [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7461645928722664737). 99 | - [Github](https://github.com/fix2015/structure_priority_queue) 100 | 101 | --- 102 | 103 | ### Day 8: Set [Lesson](https://github.com/fix2015/structure_tutorial/tree/main/set/README.md) 104 | - **0-5 minutes**: Check the Home Task from Day 7 (Review solutions and discuss any issues). 105 | - **5-10 minutes**: Introduction to Set and its key operations: `add(value)`, `has(value)`, `delete(value)`. 106 | - **10-20 minutes**: Implement a Set class from scratch. 107 | - **20-30 minutes**: Task - Remove duplicates from an array using Set (Interview problem). 108 | - **30-40 minutes**: Home Task [Task](https://github.com/fix2015/structure_tutorial/tree/main/set/task.md). 109 | - **Video Tutorial**: [Watch the Video](#). 110 | - [Github](https://github.com/fix2015/structure_set) 111 | 112 | --- 113 | 114 | ### Day 9: Trie (Prefix Tree) [Lesson](https://github.com/fix2015/structure_tutorial/tree/main/trie/README.md) 115 | - **0-5 minutes**: Check the Home Task from Day 8 (Review solutions and discuss any issues). 116 | - **5-10 minutes**: Introduction to Trie, its structure, and operations. 117 | - **10-20 minutes**: Implement a Trie class from scratch. 118 | - **20-30 minutes**: Task - Build an Autocomplete system using Trie (Interview problem). 119 | - **30-40 minutes**: Home Task [Task](https://github.com/fix2015/structure_tutorial/tree/main/trie/task.md). 120 | - **Video Tutorial**: [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7461653464670670112). 121 | - [Github](https://github.com/fix2015/structure_trie) 122 | 123 | --- 124 | 125 | ### Day 10: Heap [Lesson](https://github.com/fix2015/structure_tutorial/tree/main/heap/README.md) 126 | - **0-5 minutes**: Check the Home Task from Day 9 (Review solutions and discuss any issues). 127 | - **5-10 minutes**: Introduction to Heap, Max Heap and Min Heap. 128 | - **10-20 minutes**: Implement a Heap class from scratch. 129 | - **20-30 minutes**: Task - Implement a Priority Queue using Heap (Interview problem). 130 | - **30-40 minutes**: Home Task [Task](https://github.com/fix2015/structure_tutorial/tree/main/heap/task.md). 131 | - **Video Tutorial**: [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7461656786873928992). 132 | - [Github](https://github.com/fix2015/structure_heap) 133 | 134 | --- 135 | 136 | ### Day 11: Deque (Double-Ended Queue) [Lesson](https://github.com/fix2015/structure_tutorial/tree/main/deque/README.md) 137 | - **0-5 minutes**: Check the Home Task from Day 10 (Review solutions and discuss any issues). 138 | - **5-10 minutes**: Introduction to Deque and its operations: `addFront(item)`, `addBack(item)`, `removeFront()`, `removeBack()`. 139 | - **10-20 minutes**: Implement a Deque class from scratch. 140 | - **20-30 minutes**: Task - Solve a sliding window problem using Deque (Interview problem). 141 | - **30-40 minutes**: Home Task [Task](https://github.com/fix2015/structure_tutorial/tree/main/bst/task.md). 142 | - **Video Tutorial**: [Watch the Video](https://www.tiktok.com/@jsmentoring/video/7461661130629451040). 143 | - [Github](https://github.com/fix2015/structure_deque) 144 | 145 | --- 146 | 147 | ### Day 12: Revision and Real-World Project 148 | - **0-5 minutes**: Check the Home Task from Day 11 (Review solutions and discuss any issues). 149 | - **5-10 minutes**: Quick review of all data structures covered. 150 | - **10-20 minutes**: Implement a real-world project using multiple data structures. 151 | - **20-30 minutes**: Solve practice problems (LeetCode, HackerRank, etc.) to test your skills. 152 | - **30-40 minutes**: Home Task - Solve a complex problem using any combination of data structures. 153 | - **Final Self-Assessment**: Evaluate your progress and identify areas for improvement. 154 | 155 | ## Tutorial Format 156 | 157 | In this series, we provide both **text-based tutorials** and **video tutorials** to help you understand each data structure in-depth. 158 | 159 | ### 1. **Text-Based Tutorials** 160 | Each data structure is explained with a detailed breakdown of its concepts, key methods, and example applications. You’ll also find code examples and practical use cases to help reinforce your understanding. 161 | 162 | ### 2. **Video Tutorials** 163 | We also have accompanying video tutorials that walk you through the same content, so you can follow along visually and learn step by step. These videos will be linked throughout the text-based tutorials for easy reference. 164 | 165 | --- 166 | 167 | ## Why Learn Data Structures? 168 | 169 | Data structures are fundamental to computer science and programming. They allow you to: 170 | - **Organize and store data** efficiently. 171 | - **Optimize performance** in algorithms. 172 | - **Solve complex problems** more easily and effectively. 173 | 174 | Understanding how and when to use different data structures is essential for writing efficient, scalable code. Whether you’re building a web app, working on a data analysis project, or preparing for coding interviews, this knowledge will give you a significant edge. 175 | 176 | --- 177 | 178 | ## Connect with Me: 179 | - [LinkedIn - Vitalii Semianchuk](https://www.linkedin.com/in/vitalii-semianchuk-9812a786/) 180 | - [Telegram - @jsmentorfree](https://t.me/jsmentorfree) - We do a lot of free teaching on this channel! Join us to learn and grow in web development. 181 | - [Tiktok - @jsmentoring](https://www.tiktok.com/@jsmentoring) Everyday new videos 182 | - [Youtube - @jsmentor-uk](https://www.youtube.com/@jsmentor-uk) Mentor live streams 183 | - [Dev.to - fix2015](https://dev.to/fix2015) Javascript featured, live, experience 184 | 185 | --- 186 | 187 | ## Conclusion 188 | 189 | We hope this tutorial series helps you master the essential data structures in programming. Stay tuned for more tutorials and practical coding examples that will improve your problem-solving skills and prepare you for real-world challenges! 190 | 191 | Feel free to reach out if you have any questions, feedback, or suggestions. 192 | 193 | Happy coding! 💻 194 | 195 | --- 196 | 197 | ## Contributing 198 | Contributions are welcome! If you have suggestions or want to add new features, feel free to create a pull request. 199 | 200 | --- 201 | 202 | ## License 203 | This project is licensed under the MIT License. 204 | 205 | --- 206 | 207 | -------------------------------------------------------------------------------- /bst/README.md: -------------------------------------------------------------------------------- 1 | # Binary Search Tree (BST) Data Structure in JavaScript 🚀 2 | 3 | ## 0-5 minutes: Check the 4 | - Review solutions. 5 | - Discuss any issues and common mistakes encountered. 6 | - Clarify doubts related to the home task. 7 | 8 | ### Key Points to Address: 9 | - If any of the students faced issues with basic concepts like **trees**, **recursion**, or **binary trees**, address those foundational concepts briefly before moving forward. 10 | - Explain the **Binary Search Tree (BST)** data structure to everyone: 11 | - A **Binary Search Tree** is a hierarchical data structure where each node has at most two children: 12 | - **Left child**: Contains values less than the parent node. 13 | - **Right child**: Contains values greater than the parent node. 14 | - It is primarily used for efficient searching, insertion, and deletion operations. 15 | 16 | ## 5-10 minutes: Introduction to Binary Search Tree and its Key Properties 17 | - Explain the **Binary Search Tree** structure and its properties: 18 | - Each node stores a value. 19 | - The left subtree of a node contains only values smaller than the node. 20 | - The right subtree of a node contains only values greater than the node. 21 | - No duplicate values are allowed in a standard BST. 22 | - Discuss key operations: 23 | - **Insert(value)**: Adds a value to the BST while maintaining the BST property. 24 | - **Search(value)**: Checks if a value exists in the BST. 25 | - **Delete(value)**: Removes a value from the BST while maintaining the BST property. 26 | - **Traversal**: 27 | - **Inorder**: Retrieves values in sorted order. 28 | - **Preorder**: Visits nodes in root-left-right order. 29 | - **Postorder**: Visits nodes in left-right-root order. 30 | 31 | ## 10-20 minutes: Implement a Binary Search Tree Class from Scratch 32 | - Guide students to implement a BST class in JavaScript. 33 | - The class should support the following methods: 34 | - `insert(value)` 35 | - `search(value)` 36 | - `delete(value)` 37 | - `inorderTraversal()` 38 | - `preorderTraversal()` 39 | - `postorderTraversal()` 40 | 41 | Example: 42 | 43 | ```javascript 44 | class Node { 45 | constructor(value) { 46 | this.value = value; 47 | this.left = null; 48 | this.right = null; 49 | } 50 | } 51 | 52 | class BinarySearchTree { 53 | constructor() { 54 | this.root = null; 55 | } 56 | 57 | // Insert a value into the BST 58 | insert(value) { 59 | const newNode = new Node(value); 60 | if (!this.root) { 61 | this.root = newNode; 62 | return; 63 | } 64 | let current = this.root; 65 | while (true) { 66 | if (value < current.value) { 67 | if (!current.left) { 68 | current.left = newNode; 69 | return; 70 | } 71 | current = current.left; 72 | } else { 73 | if (!current.right) { 74 | current.right = newNode; 75 | return; 76 | } 77 | current = current.right; 78 | } 79 | } 80 | } 81 | 82 | // Search for a value in the BST 83 | search(value) { 84 | let current = this.root; 85 | while (current) { 86 | if (value === current.value) return true; 87 | current = value < current.value ? current.left : current.right; 88 | } 89 | return false; 90 | } 91 | 92 | // Inorder traversal (sorted order) 93 | inorderTraversal(node = this.root, result = []) { 94 | if (node) { 95 | this.inorderTraversal(node.left, result); 96 | result.push(node.value); 97 | this.inorderTraversal(node.right, result); 98 | } 99 | return result; 100 | } 101 | } 102 | 103 | // Example usage: 104 | const bst = new BinarySearchTree(); 105 | bst.insert(10); 106 | bst.insert(5); 107 | bst.insert(15); 108 | bst.insert(7); 109 | console.log(bst.search(7)); // true 110 | console.log(bst.inorderTraversal()); // [5, 7, 10, 15] 111 | ``` 112 | 113 | ## 20-30 minutes: Task - Solve a Problem Using Binary Search Tree 114 | - Assign a task where students need to solve a problem using a BST. 115 | - Example problem: Find the **kth smallest element** in a BST. 116 | 117 | Example: 118 | 119 | ```javascript 120 | function kthSmallest(root, k) { 121 | const inorder = []; 122 | 123 | function inorderTraversal(node) { 124 | if (!node) return; 125 | inorderTraversal(node.left); 126 | inorder.push(node.value); 127 | inorderTraversal(node.right); 128 | } 129 | 130 | inorderTraversal(root); 131 | return inorder[k - 1]; 132 | } 133 | ``` 134 | 135 | ## 30-40 minutes: Home Task - Solve a Problem Using BST from LeetCode 136 | - Provide a LeetCode problem that can be solved using a BST. 137 | - Students can work on this problem during the session or as homework. 138 | 139 | --- 140 | 141 | ## Connect with Me: 142 | - [LinkedIn - Vitalii Semianchuk](https://www.linkedin.com/in/vitalii-semianchuk-9812a786/) 143 | - [Telegram - @jsmentorfree](https://t.me/jsmentorfree) - We do a lot of free teaching on this channel! Join us to learn and grow in web development. 144 | - [Tiktok - @jsmentoring](https://www.tiktok.com/@jsmentoring) Everyday new videos 145 | - [Youtube - @jsmentor-uk](https://www.youtube.com/@jsmentor-uk) Mentor live streams 146 | - [Dev.to - fix2015](https://dev.to/fix2015) Javascript featured, live, experience -------------------------------------------------------------------------------- /bst/index.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(value) { 3 | this.value = value; 4 | this.left = null; 5 | this.right = null; 6 | } 7 | } 8 | 9 | class BinarySearchTree { 10 | constructor() { 11 | this.root = null; 12 | this.size = 0; 13 | } 14 | 15 | // Insert a value into the BST 16 | insert(value) { 17 | const newNode = new Node(value); 18 | if (this.root === null) { 19 | this.root = newNode; 20 | } else { 21 | this.insertNode(this.root, newNode); 22 | } 23 | this.size++; 24 | } 25 | 26 | // Helper function to insert a node 27 | insertNode(node, newNode) { 28 | if (newNode.value < node.value) { 29 | if (node.left === null) { 30 | node.left = newNode; 31 | } else { 32 | this.insertNode(node.left, newNode); 33 | } 34 | } else { 35 | if (node.right === null) { 36 | node.right = newNode; 37 | } else { 38 | this.insertNode(node.right, newNode); 39 | } 40 | } 41 | } 42 | 43 | // Search for a node by its value 44 | search(value) { 45 | return this.searchNode(this.root, value); 46 | } 47 | 48 | // Helper function to search for a node 49 | searchNode(node, value) { 50 | if (node === null) { 51 | return null; 52 | } 53 | if (value < node.value) { 54 | return this.searchNode(node.left, value); 55 | } else if (value > node.value) { 56 | return this.searchNode(node.right, value); 57 | } else { 58 | return node; // Node found 59 | } 60 | } 61 | 62 | // Delete a node by its value 63 | delete(value) { 64 | this.root = this.deleteNode(this.root, value); 65 | this.size--; 66 | } 67 | 68 | // Helper function to delete a node 69 | deleteNode(node, value) { 70 | if (node === null) { 71 | return null; 72 | } 73 | if (value < node.value) { 74 | node.left = this.deleteNode(node.left, value); 75 | } else if (value > node.value) { 76 | node.right = this.deleteNode(node.right, value); 77 | } else { 78 | // Node found 79 | if (node.left === null) { 80 | return node.right; 81 | } else if (node.right === null) { 82 | return node.left; 83 | } 84 | node.value = this.minNode(node.right).value; 85 | node.right = this.deleteNode(node.right, node.value); 86 | } 87 | return node; 88 | } 89 | 90 | // Helper function to find the minimum node 91 | minNode(node) { 92 | while (node && node.left !== null) { 93 | node = node.left; 94 | } 95 | return node; 96 | } 97 | 98 | // In-order traversal (left, root, right) 99 | inOrder() { 100 | this.inOrderTraverseNode(this.root); 101 | } 102 | 103 | // Helper function for in-order traversal 104 | inOrderTraverseNode(node) { 105 | if (node !== null) { 106 | this.inOrderTraverseNode(node.left); 107 | console.log(node.value); 108 | this.inOrderTraverseNode(node.right); 109 | } 110 | } 111 | 112 | // Get the size of the BST 113 | size() { 114 | return this.size; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /bst/task.md: -------------------------------------------------------------------------------- 1 | ### Task 1: Validate Binary Search Tree 2 | **Problem:** 3 | Given a binary tree, determine if it is a valid binary search tree (BST). A valid BST is defined as: 4 | - The left subtree of a node contains only nodes with keys less than the node’s key. 5 | - The right subtree of a node contains only nodes with keys greater than the node’s key. 6 | - Both the left and right subtrees must also be binary search trees. 7 | 8 | **Input:** 9 | - Tree: 10 | ``` 11 | 2 12 | / \ 13 | 1 3 14 | ``` 15 | 16 | **Output:** 17 | - Result: `true` 18 | 19 | --- 20 | 21 | ### Task 2: Inorder Traversal of Binary Search Tree 22 | **Problem:** 23 | Given a binary search tree, return the inorder traversal of its nodes' values. The inorder traversal of a BST should return the values in sorted order. 24 | 25 | **Input:** 26 | - Tree: 27 | ``` 28 | 4 29 | / \ 30 | 2 6 31 | / \ / \ 32 | 1 3 5 7 33 | ``` 34 | 35 | **Output:** 36 | - Result: `[1, 2, 3, 4, 5, 6, 7]` 37 | 38 | --- 39 | 40 | ### Task 3: Find the Kth Smallest Element in a BST 41 | **Problem:** 42 | Given a binary search tree, find the `k`th smallest element in it. 43 | 44 | **Input:** 45 | - Tree: 46 | ``` 47 | 5 48 | / \ 49 | 3 6 50 | / \ 51 | 2 4 52 | ``` 53 | - k: `3` 54 | 55 | **Output:** 56 | - Result: `3` 57 | 58 | --- 59 | 60 | ### Task 4: Convert Sorted Array to Binary Search Tree 61 | **Problem:** 62 | Given a sorted array, convert it to a balanced binary search tree. 63 | 64 | **Input:** 65 | - Array: `[1, 2, 3, 4, 5, 6, 7]` 66 | 67 | **Output:** 68 | - Result: 69 | ``` 70 | 4 71 | / \ 72 | 2 6 73 | / \ / \ 74 | 1 3 5 7 75 | ``` 76 | 77 | --- 78 | 79 | ### Task 5: Lowest Common Ancestor in a Binary Search Tree 80 | **Problem:** 81 | Given a binary search tree and two node values, find their lowest common ancestor (LCA). The LCA of two nodes `p` and `q` in a BST is defined as the lowest node that is an ancestor of both `p` and `q`. 82 | 83 | **Input:** 84 | - Tree: 85 | ``` 86 | 6 87 | / \ 88 | 2 8 89 | / \ / \ 90 | 0 4 7 9 91 | / \ 92 | 3 5 93 | ``` 94 | - Nodes: `p = 2`, `q = 8` 95 | 96 | **Output:** 97 | - Result: `6` 98 | 99 | --- 100 | 101 | ### Task 6: Delete a Node in a Binary Search Tree 102 | **Problem:** 103 | Given a binary search tree and a node to be deleted, delete the node and return the new tree. After deleting a node: 104 | - If the node has no children, simply remove it. 105 | - If the node has one child, replace the node with its child. 106 | - If the node has two children, find the node's in-order successor (smallest node in the right subtree), replace the node with its in-order successor, and delete the in-order successor. 107 | 108 | **Input:** 109 | - Tree: 110 | ``` 111 | 5 112 | / \ 113 | 3 6 114 | / \ 115 | 2 4 116 | ``` 117 | - Node to delete: `3` 118 | 119 | **Output:** 120 | - Result: 121 | ``` 122 | 5 123 | / \ 124 | 4 6 125 | / 126 | 2 127 | ``` 128 | 129 | --- 130 | 131 | ### Task 7: Balance a Binary Search Tree 132 | **Problem:** 133 | Given a binary search tree, balance the tree so that the depth of the two subtrees of every node never differs by more than one. 134 | 135 | **Input:** 136 | - Tree: 137 | ``` 138 | 1 139 | \ 140 | 2 141 | \ 142 | 3 143 | \ 144 | 4 145 | ``` 146 | 147 | **Output:** 148 | - Result: 149 | ``` 150 | 2 151 | / \ 152 | 1 3 153 | \ 154 | 4 155 | ``` 156 | 157 | --- 158 | 159 | ### Task 8: Count the Number of Nodes in a Binary Search Tree 160 | **Problem:** 161 | Given a binary search tree, count the number of nodes in the tree. 162 | 163 | **Input:** 164 | - Tree: 165 | ``` 166 | 4 167 | / \ 168 | 2 6 169 | / \ / \ 170 | 1 3 5 7 171 | ``` 172 | 173 | **Output:** 174 | - Result: `7` 175 | 176 | --- 177 | 178 | ### Task 9: Search in a Binary Search Tree 179 | **Problem:** 180 | Given a binary search tree and a value `val`, return the node where the value is located, or `null` if the value is not found. 181 | 182 | **Input:** 183 | - Tree: 184 | ``` 185 | 5 186 | / \ 187 | 3 6 188 | / \ 189 | 2 4 190 | ``` 191 | - Value: `4` 192 | 193 | **Output:** 194 | - Result: `4` 195 | 196 | --- 197 | 198 | ### Task 10: Serialize and Deserialize a Binary Search Tree 199 | **Problem:** 200 | Design an algorithm to serialize and deserialize a binary search tree. Serialization is the process of converting a binary search tree into a string representation, and deserialization is the process of converting a string back into the binary search tree. 201 | 202 | **Input:** 203 | - Tree: 204 | ``` 205 | 5 206 | / \ 207 | 3 6 208 | / \ 209 | 2 4 210 | ``` 211 | 212 | **Output:** 213 | - Result: `"5,3,2,#,#,4,#,#,6,#,#"` 214 | --- 215 | -------------------------------------------------------------------------------- /deque/README.md: -------------------------------------------------------------------------------- 1 | # Deque Data Structure in JavaScript 🚀 2 | 3 | ## 0-5 minutes: Check the Home Task 4 | - Review solutions. 5 | - Discuss any issues and common mistakes encountered. 6 | - Clarify doubts related to the home task. 7 | 8 | ### Key Points to Address: 9 | - If any of the students faced issues with basic concepts like **arrays**, **queues**, or **stacks**, address those foundational concepts briefly before moving forward. 10 | - Explain the **Deque** data structure to everyone: 11 | - A **Deque** (Double-Ended Queue) is a generalized form of a queue that allows insertion and deletion at both ends. 12 | - It can function as both a queue (FIFO) and a stack (LIFO). 13 | - Common operations: 14 | - **addFront(item)**: Adds an item to the front of the deque. 15 | - **addRear(item)**: Adds an item to the rear of the deque. 16 | - **removeFront()**: Removes an item from the front of the deque. 17 | - **removeRear()**: Removes an item from the rear of the deque. 18 | - **peekFront()**: Returns the front item without removing it. 19 | - **peekRear()**: Returns the rear item without removing it. 20 | - **isEmpty()**: Checks if the deque is empty. 21 | 22 | ## 5-10 minutes: Introduction to Deque and its Key Operations 23 | - Explain the **Deque** data structure and its real-world analogy (like a double-sided conveyor belt where items can be added or removed from either end). 24 | - Discuss key operations: 25 | - **addFront(item)**: Adds an item to the front. 26 | - **addRear(item)**: Adds an item to the rear. 27 | - **removeFront()**: Removes an item from the front. 28 | - **removeRear()**: Removes an item from the rear. 29 | - **peekFront()**: Views the front item without removing it. 30 | - **peekRear()**: Views the rear item without removing it. 31 | - **isEmpty()**: Checks if the deque is empty. 32 | 33 | ## 10-20 minutes: Implement a Deque Class from Scratch 34 | - Guide students to implement a Deque class in JavaScript. 35 | - The class should support the following methods: 36 | - `addFront(item)` 37 | - `addRear(item)` 38 | - `removeFront()` 39 | - `removeRear()` 40 | - `peekFront()` 41 | - `peekRear()` 42 | - `isEmpty()` 43 | 44 | Example: 45 | 46 | ```javascript 47 | class Deque { 48 | constructor() { 49 | this.items = []; 50 | } 51 | 52 | // Add item to the front 53 | addFront(item) { 54 | this.items.unshift(item); 55 | } 56 | 57 | // Add item to the rear 58 | addRear(item) { 59 | this.items.push(item); 60 | } 61 | 62 | // Remove item from the front 63 | removeFront() { 64 | if (this.isEmpty()) { 65 | return 'Deque is empty'; 66 | } 67 | return this.items.shift(); 68 | } 69 | 70 | // Remove item from the rear 71 | removeRear() { 72 | if (this.isEmpty()) { 73 | return 'Deque is empty'; 74 | } 75 | return this.items.pop(); 76 | } 77 | 78 | // View the front item 79 | peekFront() { 80 | if (this.isEmpty()) { 81 | return 'Deque is empty'; 82 | } 83 | return this.items[0]; 84 | } 85 | 86 | // View the rear item 87 | peekRear() { 88 | if (this.isEmpty()) { 89 | return 'Deque is empty'; 90 | } 91 | return this.items[this.items.length - 1]; 92 | } 93 | 94 | // Check if the deque is empty 95 | isEmpty() { 96 | return this.items.length === 0; 97 | } 98 | } 99 | 100 | // Example usage: 101 | const deque = new Deque(); 102 | deque.addFront(10); 103 | deque.addRear(20); 104 | deque.addFront(5); 105 | console.log(deque.peekFront()); // 5 106 | console.log(deque.peekRear()); // 20 107 | deque.removeFront(); 108 | console.log(deque.peekFront()); // 10 109 | deque.removeRear(); 110 | console.log(deque.isEmpty()); // false 111 | ``` 112 | 113 | ## 20-30 minutes: Task - Solve a Problem Using a Deque 114 | - Assign a task where students need to solve a problem using the Deque. 115 | - Example problem: Implement a sliding window maximum using a Deque. 116 | 117 | Example: 118 | 119 | ```javascript 120 | function maxSlidingWindow(nums, k) { 121 | const deque = []; 122 | const result = []; 123 | 124 | for (let i = 0; i < nums.length; i++) { 125 | // Remove elements not within the sliding window 126 | if (deque.length && deque[0] < i - k + 1) { 127 | deque.shift(); 128 | } 129 | 130 | // Remove smaller elements from the rear of the deque 131 | while (deque.length && nums[deque[deque.length - 1]] < nums[i]) { 132 | deque.pop(); 133 | } 134 | 135 | // Add the current element index to the deque 136 | deque.push(i); 137 | 138 | // Add the maximum element of the window to the result 139 | if (i >= k - 1) { 140 | result.push(nums[deque[0]]); 141 | } 142 | } 143 | 144 | return result; 145 | } 146 | 147 | console.log(maxSlidingWindow([1, 3, -1, -3, 5, 3, 6, 7], 3)); // [3, 3, 5, 5, 6, 7] 148 | ``` 149 | 150 | ## 30-40 minutes: Home Task - Solve a Problem Using Deque from LeetCode 151 | - Provide a LeetCode problem that can be solved using the Deque data structure. 152 | - Students can work on this problem during the session or as homework. 153 | 154 | --- 155 | 156 | ## Connect with Me: 157 | - [LinkedIn - Vitalii Semianchuk](https://www.linkedin.com/in/vitalii-semianchuk-9812a786/) 158 | - [Telegram - @jsmentorfree](https://t.me/jsmentorfree) - We do a lot of free teaching on this channel! Join us to learn and grow in web development. 159 | - [Tiktok - @jsmentoring](https://www.tiktok.com/@jsmentoring) Everyday new videos 160 | - [Youtube - @jsmentor-uk](https://www.youtube.com/@jsmentor-uk) Mentor live streams 161 | - [Dev.to - fix2015](https://dev.to/fix2015) Javascript featured, live, experience -------------------------------------------------------------------------------- /deque/index.js: -------------------------------------------------------------------------------- 1 | class Deque { 2 | constructor() { 3 | this.items = []; 4 | } 5 | 6 | // Add an element to the front of the deque 7 | insertFront(element) { 8 | this.items.unshift(element); 9 | } 10 | 11 | // Add an element to the back of the deque 12 | insertBack(element) { 13 | this.items.push(element); 14 | } 15 | 16 | // Remove and return the element from the front of the deque 17 | removeFront() { 18 | if (this.isEmpty()) { 19 | return "Deque is empty!"; 20 | } 21 | return this.items.shift(); 22 | } 23 | 24 | // Remove and return the element from the back of the deque 25 | removeBack() { 26 | if (this.isEmpty()) { 27 | return "Deque is empty!"; 28 | } 29 | return this.items.pop(); 30 | } 31 | 32 | // Peek at the element at the front without removing it 33 | peekFront() { 34 | if (this.isEmpty()) { 35 | return "Deque is empty!"; 36 | } 37 | return this.items[0]; 38 | } 39 | 40 | // Peek at the element at the back without removing it 41 | peekBack() { 42 | if (this.isEmpty()) { 43 | return "Deque is empty!"; 44 | } 45 | return this.items[this.items.length - 1]; 46 | } 47 | 48 | // Get the size of the deque 49 | size() { 50 | return this.items.length; 51 | } 52 | 53 | // Check if the deque is empty 54 | isEmpty() { 55 | return this.items.length === 0; 56 | } 57 | } 58 | 59 | // Initialize the deque 60 | const deque = new Deque(); 61 | 62 | // Insert elements at the front and back 63 | deque.insertFront(10); 64 | deque.insertBack(20); 65 | deque.insertFront(5); 66 | 67 | // Peek at the front and back elements 68 | console.log(deque.peekFront()); // Output: 5 69 | console.log(deque.peekBack()); // Output: 20 70 | 71 | // Remove elements from the front and back 72 | console.log(deque.removeFront()); // Output: 5 73 | console.log(deque.removeBack()); // Output: 20 74 | 75 | // Get the size of the deque 76 | console.log(deque.size()); // Output: 1 77 | 78 | // Check if the deque is empty 79 | console.log(deque.isEmpty()); // Output: false 80 | -------------------------------------------------------------------------------- /deque/task.md: -------------------------------------------------------------------------------- 1 | ### Task 1: Sliding Window Maximum 2 | **Problem:** 3 | Given an array of integers and a sliding window size `k`, find the maximum value in each sliding window of size `k`. 4 | 5 | **Input:** 6 | - Array: `[1, 3, -1, -3, 5, 3, 6, 7]` 7 | - Window size: `3` 8 | 9 | **Output:** 10 | - Result: `[3, 3, 5, 5, 6, 7]` 11 | 12 | --- 13 | 14 | ### Task 2: Design a Circular Deque 15 | **Problem:** 16 | Design a circular deque that supports the following operations: 17 | - `insertFront`: Adds an item at the front of the deque. 18 | - `insertLast`: Adds an item at the rear of the deque. 19 | - `deleteFront`: Deletes an item from the front of the deque. 20 | - `deleteLast`: Deletes an item from the rear of the deque. 21 | - `getFront`: Gets the front item from the deque. 22 | - `getRear`: Gets the last item from the deque. 23 | - `isEmpty`: Checks if the deque is empty. 24 | - `isFull`: Checks if the deque is full. 25 | 26 | **Input:** 27 | - Operations: 28 | ``` 29 | insertFront(1) 30 | insertLast(2) 31 | getFront() 32 | getRear() 33 | deleteFront() 34 | deleteLast() 35 | isEmpty() 36 | ``` 37 | 38 | **Output:** 39 | - Result: `[1, 2, 1, 2, false]` 40 | 41 | --- 42 | 43 | ### Task 3: Implement Stack Using Deque 44 | **Problem:** 45 | Implement a stack using a deque (double-ended queue). The stack should support the following operations: 46 | - `push(x)`: Pushes an element onto the stack. 47 | - `pop()`: Removes the top element from the stack. 48 | - `top()`: Returns the top element of the stack. 49 | - `empty()`: Returns whether the stack is empty. 50 | 51 | **Input:** 52 | - Operations: 53 | ``` 54 | push(1) 55 | push(2) 56 | top() 57 | pop() 58 | empty() 59 | ``` 60 | 61 | **Output:** 62 | - Result: `[2, 2, false]` 63 | 64 | --- 65 | 66 | ### Task 4: Palindrome Checker Using Deque 67 | **Problem:** 68 | Given a string, check if it is a palindrome using a deque. A palindrome is a word, phrase, or sequence that reads the same backward as forward. 69 | 70 | **Input:** 71 | - String: `"racecar"` 72 | 73 | **Output:** 74 | - Result: `true` 75 | 76 | --- 77 | 78 | ### Task 5: First Unique Character in a Stream 79 | **Problem:** 80 | Design a data structure that supports the following operations on a stream of characters: 81 | - `insert(c)`: Inserts a character `c` into the stream. 82 | - `firstUniq()`: Returns the first unique character in the stream. 83 | 84 | **Input:** 85 | - Stream: `"aabcc"` 86 | 87 | **Output:** 88 | - Result: `["a", "b", "c", "c", ""]` 89 | 90 | --- 91 | 92 | ### Task 6: Maximal Rectangle 93 | **Problem:** 94 | Given a 2D matrix filled with `0`'s and `1`'s, find the largest rectangle containing only `1`'s and return its area. Use a deque to optimize the solution. 95 | 96 | **Input:** 97 | - Matrix: 98 | ``` 99 | [ 100 | ["1", "0", "1", "0", "0"], 101 | ["1", "0", "1", "1", "1"], 102 | ["1", "1", "1", "1", "1"], 103 | ["1", "0", "0", "1", "0"] 104 | ] 105 | ``` 106 | 107 | **Output:** 108 | - Result: `6` 109 | 110 | --- 111 | 112 | ### Task 7: Remove Duplicate Letters 113 | **Problem:** 114 | Given a string, remove duplicate letters so that every letter appears once and only once. The result should be the smallest lexicographical order of the possible answers. 115 | 116 | **Input:** 117 | - String: `"bcabc"` 118 | 119 | **Output:** 120 | - Result: `"abc"` 121 | 122 | --- 123 | 124 | ### Task 8: Sort a Deque 125 | **Problem:** 126 | Sort a deque of integers in ascending order. 127 | 128 | **Input:** 129 | - Deque: `[3, 1, 4, 1, 5, 9, 2, 6]` 130 | 131 | **Output:** 132 | - Result: `[1, 1, 2, 3, 4, 5, 6, 9]` 133 | 134 | --- 135 | 136 | ### Task 9: Reverse Subarray Using Deque 137 | **Problem:** 138 | Given an array, reverse a subarray of size `k` in the array using a deque. 139 | 140 | **Input:** 141 | - Array: `[1, 2, 3, 4, 5, 6]` 142 | - `k`: `3` 143 | 144 | **Output:** 145 | - Result: `[3, 2, 1, 4, 5, 6]` 146 | 147 | --- 148 | 149 | ### Task 10: Remove All Adjacent Duplicates Using Deque 150 | **Problem:** 151 | Given a string, remove all adjacent duplicates using a deque. The operation is repeated until no more adjacent duplicates exist. 152 | 153 | **Input:** 154 | - String: `"abbaca"` 155 | 156 | **Output:** 157 | - Result: `"ca"` 158 | 159 | --- 160 | -------------------------------------------------------------------------------- /graph/README.md: -------------------------------------------------------------------------------- 1 | # Graph Data Structure in JavaScript 🚀 2 | 3 | ## 0-5 minutes: Check the Home Task 4 | - Review solutions. 5 | - Discuss any issues and common mistakes encountered. 6 | - Clarify doubts related to the home task. 7 | 8 | ### Key Points to Address: 9 | - If any of the students faced issues with basic concepts like **arrays**, **linked lists**, or **trees**, address those foundational concepts briefly before moving forward. 10 | - Explain the **Graph** data structure to everyone: 11 | - A **Graph** is a collection of **nodes** (or vertices) connected by **edges**. 12 | - It can represent various real-world systems, such as social networks, road maps, or computer networks. 13 | - Types of graphs: 14 | - **Directed Graph**: Edges have a direction (e.g., one-way streets). 15 | - **Undirected Graph**: Edges have no direction (e.g., two-way streets). 16 | - **Weighted Graph**: Edges have weights (e.g., distances or costs). 17 | - **Unweighted Graph**: All edges are equal. 18 | - Graphs can be represented using: 19 | - **Adjacency Matrix** 20 | - **Adjacency List** 21 | 22 | ## 5-10 minutes: Introduction to Graph and its Key Operations 23 | - Explain the **Graph** data structure and its real-world analogy (like a road map where intersections are nodes and roads are edges). 24 | - Discuss key operations: 25 | - **addVertex(vertex)**: Adds a vertex to the graph. 26 | - **addEdge(vertex1, vertex2, weight)**: Adds an edge between two vertices (with an optional weight). 27 | - **removeVertex(vertex)**: Removes a vertex and all its connected edges. 28 | - **removeEdge(vertex1, vertex2)**: Removes the edge between two vertices. 29 | - **traverseGraph(startVertex)**: Traverses the graph using algorithms like BFS (Breadth-First Search) or DFS (Depth-First Search). 30 | 31 | ## 10-20 minutes: Implement a Graph Class from Scratch 32 | - Guide students to implement a Graph class in JavaScript using an adjacency list. 33 | - The class should support the following methods: 34 | - `addVertex(vertex)` 35 | - `addEdge(vertex1, vertex2)` 36 | - `removeVertex(vertex)` 37 | - `removeEdge(vertex1, vertex2)` 38 | - `printGraph()` 39 | 40 | Example: 41 | 42 | ```javascript 43 | class Graph { 44 | constructor() { 45 | this.adjacencyList = {}; 46 | } 47 | 48 | // Adds a vertex to the graph 49 | addVertex(vertex) { 50 | if (!this.adjacencyList[vertex]) { 51 | this.adjacencyList[vertex] = []; 52 | } 53 | } 54 | 55 | // Adds an edge between two vertices 56 | addEdge(vertex1, vertex2) { 57 | if (this.adjacencyList[vertex1]) { 58 | this.adjacencyList[vertex1].push(vertex2); 59 | } 60 | if (this.adjacencyList[vertex2]) { 61 | this.adjacencyList[vertex2].push(vertex1); 62 | } 63 | } 64 | 65 | // Removes an edge between two vertices 66 | removeEdge(vertex1, vertex2) { 67 | this.adjacencyList[vertex1] = this.adjacencyList[vertex1].filter( 68 | v => v !== vertex2 69 | ); 70 | this.adjacencyList[vertex2] = this.adjacencyList[vertex2].filter( 71 | v => v !== vertex1 72 | ); 73 | } 74 | 75 | // Removes a vertex and all its edges 76 | removeVertex(vertex) { 77 | while (this.adjacencyList[vertex]?.length) { 78 | const adjacentVertex = this.adjacencyList[vertex].pop(); 79 | this.removeEdge(vertex, adjacentVertex); 80 | } 81 | delete this.adjacencyList[vertex]; 82 | } 83 | 84 | // Prints the graph 85 | printGraph() { 86 | for (let vertex in this.adjacencyList) { 87 | console.log(vertex, '->', this.adjacencyList[vertex].join(', ')); 88 | } 89 | } 90 | } 91 | 92 | // Example usage: 93 | const graph = new Graph(); 94 | graph.addVertex('A'); 95 | graph.addVertex('B'); 96 | graph.addVertex('C'); 97 | graph.addEdge('A', 'B'); 98 | graph.addEdge('A', 'C'); 99 | graph.addEdge('B', 'C'); 100 | graph.printGraph(); 101 | /* 102 | Output: 103 | A -> B, C 104 | B -> A, C 105 | C -> A, B 106 | */ 107 | ``` 108 | 109 | ## 20-30 minutes: Task - Solve a Problem Using a Graph 110 | - Assign a task where students need to solve a problem using the Graph. 111 | - Example problem: Find the shortest path between two nodes using BFS. 112 | 113 | Example: 114 | 115 | ```javascript 116 | function bfsShortestPath(graph, start, target) { 117 | const queue = [[start]]; 118 | const visited = new Set(); 119 | 120 | while (queue.length > 0) { 121 | const path = queue.shift(); 122 | const node = path[path.length - 1]; 123 | 124 | if (node === target) { 125 | return path; 126 | } 127 | 128 | if (!visited.has(node)) { 129 | visited.add(node); 130 | 131 | for (const neighbor of graph[node]) { 132 | const newPath = [...path, neighbor]; 133 | queue.push(newPath); 134 | } 135 | } 136 | } 137 | 138 | return null; // No path found 139 | } 140 | 141 | const graph = { 142 | A: ['B', 'C'], 143 | B: ['A', 'D', 'E'], 144 | C: ['A', 'F'], 145 | D: ['B'], 146 | E: ['B', 'F'], 147 | F: ['C', 'E'] 148 | }; 149 | 150 | console.log(bfsShortestPath(graph, 'A', 'F')); // [ 'A', 'C', 'F' ] 151 | ``` 152 | 153 | ## 30-40 minutes: Home Task - Solve a Problem Using Graph from LeetCode 154 | - Provide a LeetCode problem that can be solved using the Graph data structure. 155 | - Students can work on this problem during the session or as homework. 156 | 157 | --- 158 | 159 | ## Connect with Me: 160 | - [LinkedIn - Vitalii Semianchuk](https://www.linkedin.com/in/vitalii-semianchuk-9812a786/) 161 | - [Telegram - @jsmentorfree](https://t.me/jsmentorfree) - We do a lot of free teaching on this channel! Join us to learn and grow in web development. 162 | - [Tiktok - @jsmentoring](https://www.tiktok.com/@jsmentoring) Everyday new videos 163 | - [Youtube - @jsmentor-uk](https://www.youtube.com/@jsmentor-uk) Mentor live streams 164 | - [Dev.to - fix2015](https://dev.to/fix2015) Javascript featured, live, experience -------------------------------------------------------------------------------- /graph/index.js: -------------------------------------------------------------------------------- 1 | class Graph { 2 | constructor() { 3 | this.vertices = {}; 4 | } 5 | 6 | // Add a new vertex to the graph 7 | addVertex(vertex) { 8 | if (!this.vertices[vertex]) { 9 | this.vertices[vertex] = []; 10 | } 11 | } 12 | 13 | // Add an edge between two vertices 14 | addEdge(vertex1, vertex2) { 15 | if (this.vertices[vertex1] && this.vertices[vertex2]) { 16 | this.vertices[vertex1].push(vertex2); 17 | this.vertices[vertex2].push(vertex1); 18 | } 19 | } 20 | 21 | // Remove a vertex from the graph 22 | removeVertex(vertex) { 23 | if (this.vertices[vertex]) { 24 | delete this.vertices[vertex]; 25 | for (let key in this.vertices) { 26 | const index = this.vertices[key].indexOf(vertex); 27 | if (index !== -1) { 28 | this.vertices[key].splice(index, 1); 29 | } 30 | } 31 | } 32 | } 33 | 34 | // Remove an edge between two vertices 35 | removeEdge(vertex1, vertex2) { 36 | if (this.vertices[vertex1] && this.vertices[vertex2]) { 37 | this.vertices[vertex1] = this.vertices[vertex1].filter(v => v !== vertex2); 38 | this.vertices[vertex2] = this.vertices[vertex2].filter(v => v !== vertex1); 39 | } 40 | } 41 | 42 | // Display the graph structure 43 | display() { 44 | console.log(this.vertices); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /graph/task.md: -------------------------------------------------------------------------------- 1 | ### Task 1: Number of Islands 2 | **Problem:** 3 | Given a 2D grid of `1`'s (land) and `0`'s (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. 4 | 5 | **Input:** 6 | - Grid: 7 | ``` 8 | [ 9 | [1, 1, 0, 0, 0], 10 | [1, 1, 0, 0, 0], 11 | [0, 0, 1, 0, 0], 12 | [0, 0, 0, 1, 1] 13 | ] 14 | ``` 15 | 16 | **Output:** 17 | - Result: `3` 18 | 19 | --- 20 | 21 | ### Task 2: Clone Graph 22 | **Problem:** 23 | Given a reference to a node in a connected undirected graph, return a deep copy (clone) of the graph. Each node in the graph contains a value and a list of its neighbors. 24 | 25 | **Input:** 26 | - Graph: 27 | ``` 28 | Node 1 -> [Node 2, Node 4] 29 | Node 2 -> [Node 1, Node 3] 30 | Node 3 -> [Node 2] 31 | Node 4 -> [Node 1] 32 | ``` 33 | 34 | **Output:** 35 | - Result: A deep copy of the graph with the same structure. 36 | 37 | --- 38 | 39 | ### Task 3: Course Schedule 40 | **Problem:** 41 | There are `n` courses you have to take, labeled from `0` to `n-1`. Some courses have prerequisites. Given an array of prerequisites, determine if it is possible for you to finish all courses. 42 | 43 | **Input:** 44 | - Courses: `2` 45 | - Prerequisites: `[[1, 0]]` 46 | 47 | **Output:** 48 | - Result: `true` 49 | 50 | --- 51 | 52 | ### Task 4: Word Ladder 53 | **Problem:** 54 | Given two words (`beginWord` and `endWord`), and a dictionary, find the length of the shortest transformation sequence from `beginWord` to `endWord`, such that only one letter can be changed at a time, and each transformed word must exist in the dictionary. 55 | 56 | **Input:** 57 | - Begin Word: `"hit"` 58 | - End Word: `"cog"` 59 | - Word List: `["hot", "dot", "dog", "lot", "log", "cog"]` 60 | 61 | **Output:** 62 | - Result: `5` 63 | 64 | --- 65 | 66 | ### Task 5: Number of Connected Components in an Undirected Graph 67 | **Problem:** 68 | Given an undirected graph, count the number of connected components in the graph. 69 | 70 | **Input:** 71 | - Graph: 72 | ``` 73 | n = 5, edges = [[0, 1], [1, 2], [3, 4]] 74 | ``` 75 | 76 | **Output:** 77 | - Result: `2` 78 | 79 | --- 80 | 81 | ### Task 6: Path Sum II 82 | **Problem:** 83 | Given a binary tree and a sum, find all root-to-leaf paths where each path’s sum equals the given sum. 84 | 85 | **Input:** 86 | - Tree: 87 | ``` 88 | 5 89 | / \ 90 | 4 8 91 | / / \ 92 | 11 13 4 93 | / \ \ 94 | 7 2 1 95 | ``` 96 | - Sum: `22` 97 | 98 | **Output:** 99 | - Result: `[[5, 4, 11, 2], [5, 8, 4, 1]]` 100 | 101 | --- 102 | 103 | ### Task 7: Detect Cycle in a Directed Graph 104 | **Problem:** 105 | Given a directed graph, detect if there is a cycle in the graph. 106 | 107 | **Input:** 108 | - Graph: `[[1, 2], [2, 3], [3, 1]]` 109 | 110 | **Output:** 111 | - Result: `true` 112 | 113 | --- 114 | 115 | ### Task 8: Graph Valid Tree 116 | **Problem:** 117 | Given a graph, determine if it is a valid tree. A valid tree means that the graph is connected and has no cycles. 118 | 119 | **Input:** 120 | - Graph: 121 | ``` 122 | n = 5, edges = [[0, 1], [0, 2], [0, 3], [1, 4]] 123 | ``` 124 | 125 | **Output:** 126 | - Result: `true` 127 | 128 | --- 129 | 130 | ### Task 9: Dijkstra's Shortest Path Algorithm 131 | **Problem:** 132 | Implement Dijkstra's algorithm to find the shortest path in a graph with weighted edges. 133 | 134 | **Input:** 135 | - Graph: 136 | ``` 137 | nodes = 5 138 | edges = [[0, 1, 2], [0, 2, 4], [1, 2, 1], [1, 3, 7], [2, 3, 3], [3, 4, 1]] 139 | ``` 140 | - Start Node: `0` 141 | 142 | **Output:** 143 | - Result: `[0, 2, 3, 6, 7]` (Shortest path from node 0 to all other nodes) 144 | 145 | --- 146 | 147 | ### Task 10: Topological Sort 148 | **Problem:** 149 | Given a directed acyclic graph (DAG), perform a topological sort. 150 | 151 | **Input:** 152 | - Graph: 153 | ``` 154 | n = 4, edges = [[0, 1], [0, 2], [1, 3], [2, 3]] 155 | ``` 156 | 157 | **Output:** 158 | - Result: `[0, 1, 2, 3]` 159 | 160 | --- 161 | -------------------------------------------------------------------------------- /hash_table/README.md: -------------------------------------------------------------------------------- 1 | # Hash Table Data Structure in JavaScript 🚀 2 | 3 | ## 0-5 minutes: Check the Home Task 4 | - Review solutions. 5 | - Discuss any issues and common mistakes encountered. 6 | - Clarify doubts related to the home task. 7 | 8 | ### Key Points to Address: 9 | - If any of the students faced issues with basic concepts like **arrays**, **objects**, or **maps**, address those foundational concepts briefly before moving forward. 10 | - Explain the **Hash Table** data structure to everyone: 11 | - A **Hash Table** is a data structure that stores key-value pairs. It uses a **hashing function** to map keys to indices in an array. 12 | - This allows for fast lookups, insertions, and deletions, typically in **O(1)** time complexity. 13 | 14 | ## 5-10 minutes: Introduction to Hash Table and its Key Operations 15 | - Explain the **Hash Table** data structure and its real-world analogy (like an index in a book). 16 | - Discuss key operations: 17 | - **set(key, value)**: Adds or updates a key-value pair in the hash table. 18 | - **get(key)**: Retrieves the value associated with a given key. 19 | - **delete(key)**: Removes a key-value pair from the hash table. 20 | - **has(key)**: Checks if a key exists in the hash table. 21 | 22 | ## 10-20 minutes: Implement a Hash Table Class from Scratch 23 | - Guide students to implement a simple Hash Table class in JavaScript. 24 | - The class should support the following methods: 25 | - `set(key, value)` 26 | - `get(key)` 27 | - `delete(key)` 28 | - `has(key)` 29 | 30 | Example: 31 | 32 | ```javascript 33 | class HashTable { 34 | constructor(size = 53) { 35 | this.table = new Array(size); 36 | } 37 | 38 | // Simple hashing function 39 | _hash(key) { 40 | let total = 0; 41 | const PRIME = 31; 42 | for (let i = 0; i < Math.min(key.length, 100); i++) { 43 | const char = key[i]; 44 | const value = char.charCodeAt(0) - 96; 45 | total = (total * PRIME + value) % this.table.length; 46 | } 47 | return total; 48 | } 49 | 50 | // Adds or updates a key-value pair 51 | set(key, value) { 52 | const index = this._hash(key); 53 | if (!this.table[index]) { 54 | this.table[index] = []; 55 | } 56 | for (let pair of this.table[index]) { 57 | if (pair[0] === key) { 58 | pair[1] = value; 59 | return; 60 | } 61 | } 62 | this.table[index].push([key, value]); 63 | } 64 | 65 | // Retrieves the value for a given key 66 | get(key) { 67 | const index = this._hash(key); 68 | if (this.table[index]) { 69 | for (let pair of this.table[index]) { 70 | if (pair[0] === key) { 71 | return pair[1]; 72 | } 73 | } 74 | } 75 | return undefined; 76 | } 77 | 78 | // Removes a key-value pair 79 | delete(key) { 80 | const index = this._hash(key); 81 | if (this.table[index]) { 82 | this.table[index] = this.table[index].filter(pair => pair[0] !== key); 83 | } 84 | } 85 | 86 | // Checks if a key exists 87 | has(key) { 88 | const index = this._hash(key); 89 | if (this.table[index]) { 90 | for (let pair of this.table[index]) { 91 | if (pair[0] === key) { 92 | return true; 93 | } 94 | } 95 | } 96 | return false; 97 | } 98 | } 99 | 100 | // Example usage: 101 | const hashTable = new HashTable(); 102 | hashTable.set('name', 'Alice'); 103 | hashTable.set('age', 25); 104 | console.log(hashTable.get('name')); // Alice 105 | console.log(hashTable.has('age')); // true 106 | hashTable.delete('age'); 107 | console.log(hashTable.has('age')); // false 108 | ``` 109 | 110 | ## 20-30 minutes: Task - Solve a Problem Using a Hash Table 111 | - Assign a task where students need to solve a problem using the Hash Table. 112 | - Example problem: Find the first non-repeating character in a string. 113 | 114 | Example: 115 | 116 | ```javascript 117 | function firstNonRepeatingChar(str) { 118 | const hashTable = new HashTable(); 119 | 120 | // Count the frequency of each character 121 | for (const char of str) { 122 | hashTable.set(char, (hashTable.get(char) || 0) + 1); 123 | } 124 | 125 | // Find the first character with a frequency of 1 126 | for (const char of str) { 127 | if (hashTable.get(char) === 1) { 128 | return char; 129 | } 130 | } 131 | 132 | return null; 133 | } 134 | 135 | console.log(firstNonRepeatingChar('swiss')); // 'w' 136 | ``` 137 | 138 | ## 30-40 minutes: Home Task - Solve a Problem Using Hash Table from LeetCode 139 | - Provide a LeetCode problem that can be solved using the Hash Table data structure. 140 | - Students can work on this problem during the session or as homework. 141 | 142 | --- 143 | 144 | ## Connect with Me: 145 | - [LinkedIn - Vitalii Semianchuk](https://www.linkedin.com/in/vitalii-semianchuk-9812a786/) 146 | - [Telegram - @jsmentorfree](https://t.me/jsmentorfree) - We do a lot of free teaching on this channel! Join us to learn and grow in web development. 147 | - [Tiktok - @jsmentoring](https://www.tiktok.com/@jsmentoring) Everyday new videos 148 | - [Youtube - @jsmentor-uk](https://www.youtube.com/@jsmentor-uk) Mentor live streams 149 | - [Dev.to - fix2015](https://dev.to/fix2015) Javascript featured, live, experience -------------------------------------------------------------------------------- /hash_table/index.js: -------------------------------------------------------------------------------- 1 | class HashTable { 2 | constructor(size = 50) { 3 | this.table = new Array(size); 4 | } 5 | 6 | // Hash function to calculate the index 7 | hash(key) { 8 | let hash = 0; 9 | for (let i = 0; i < key.length; i++) { 10 | hash = (hash << 5) + hash + key.charCodeAt(i); 11 | } 12 | return hash % this.table.length; 13 | } 14 | 15 | // Insert a key-value pair into the hash table 16 | insert(key, value) { 17 | const index = this.hash(key); 18 | if (!this.table[index]) { 19 | this.table[index] = []; 20 | } 21 | this.table[index].push([key, value]); 22 | } 23 | 24 | // Delete a key-value pair from the hash table 25 | delete(key) { 26 | const index = this.hash(key); 27 | if (this.table[index]) { 28 | this.table[index] = this.table[index].filter(([k, v]) => k !== key); 29 | } 30 | } 31 | 32 | // Search for a value by its key 33 | search(key) { 34 | const index = this.hash(key); 35 | if (this.table[index]) { 36 | for (let [k, v] of this.table[index]) { 37 | if (k === key) { 38 | return v; 39 | } 40 | } 41 | } 42 | return null; 43 | } 44 | 45 | // Get the size of the hash table 46 | size() { 47 | let count = 0; 48 | for (let bucket of this.table) { 49 | if (bucket) { 50 | count += bucket.length; 51 | } 52 | } 53 | return count; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /hash_table/task.md: -------------------------------------------------------------------------------- 1 | ### Task 1: Two Sum 2 | **Problem:** 3 | Given an array of integers, return the indices of the two numbers such that they add up to a specific target. You may assume that each input would have exactly one solution, and you may not use the same element twice. 4 | 5 | **Input:** 6 | - Array: `[2, 7, 11, 15]` 7 | - Target: `9` 8 | 9 | **Output:** 10 | - Result: `[0, 1]` 11 | 12 | --- 13 | 14 | ### Task 2: Group Anagrams 15 | **Problem:** 16 | Given an array of strings, group the anagrams together. You may return the answer in any order. 17 | 18 | **Input:** 19 | - Strings: `["eat", "tea", "tan", "ate", "nat", "bat"]` 20 | 21 | **Output:** 22 | - Result: `[["eat", "tea", "ate"], ["tan", "nat"], ["bat"]]` 23 | 24 | --- 25 | 26 | ### Task 3: Valid Sudoku 27 | **Problem:** 28 | Determine if a `9x9` Sudoku board is valid. Only the filled cells need to be validated according to the following rules: 29 | - Each row must contain the digits `1-9` without repetition. 30 | - Each column must contain the digits `1-9` without repetition. 31 | - Each of the nine `3x3` subgrids must contain the digits `1-9` without repetition. 32 | 33 | **Input:** 34 | - Board: 35 | 36 | ``` 37 | [ ["5", "3", ".", ".", "7", ".", ".", ".", "."], ["6", ".", ".", "1", "9", "5", ".", ".", "."], [".", "9", "8", ".", ".", ".", ".", "6", "."], ["8", ".", ".", ".", "6", ".", ".", ".", "3"], ["4", ".", ".", "8", ".", "3", ".", ".", "1"], ["7", ".", ".", ".", "2", ".", ".", ".", "6"], [".", "6", ".", ".", ".", ".", "2", "8", "."], [".", ".", ".", "4", "1", "9", ".", ".", "5"], [".", ".", ".", ".", "8", ".", ".", "7", "9"] ] 38 | ``` 39 | 40 | 41 | **Output:** 42 | - Result: `true` 43 | 44 | --- 45 | 46 | ### Task 4: Intersection of Two Arrays 47 | **Problem:** 48 | Given two arrays, write a function to compute their intersection. Each element in the result must be unique and returned in any order. 49 | 50 | **Input:** 51 | - Array 1: `[1, 2, 2, 1]` 52 | - Array 2: `[2, 2]` 53 | 54 | **Output:** 55 | - Result: `[2]` 56 | 57 | --- 58 | 59 | ### Task 5: Contains Duplicate 60 | **Problem:** 61 | Given an integer array, return `true` if any value appears at least twice in the array, and return `false` if every element is distinct. 62 | 63 | **Input:** 64 | - Array: `[1, 2, 3, 1]` 65 | 66 | **Output:** 67 | - Result: `true` 68 | 69 | --- 70 | 71 | ### Task 6: Find All Duplicates in an Array 72 | **Problem:** 73 | Given an integer array, find all the elements that appear twice in the array. 74 | 75 | **Input:** 76 | - Array: `[4, 3, 2, 7, 8, 2, 3, 1]` 77 | 78 | **Output:** 79 | - Result: `[2, 3]` 80 | 81 | --- 82 | 83 | ### Task 7: First Unique Character in a String 84 | **Problem:** 85 | Given a string, find the first non-repeating character in it and return its index. If it doesn't exist, return `-1`. 86 | 87 | **Input:** 88 | - String: `"leetcode"` 89 | 90 | **Output:** 91 | - Result: `0` 92 | 93 | --- 94 | 95 | ### Task 8: Happy Number 96 | **Problem:** 97 | Write an algorithm to determine if a number is "happy". A happy number is a number where, starting with any positive integer, replacing the number by the sum of the squares of its digits, eventually results in `1`. If a cycle is detected, the number is not a happy number. 98 | 99 | **Input:** 100 | - Number: `19` 101 | 102 | **Output:** 103 | - Result: `true` 104 | 105 | --- 106 | 107 | ### Task 9: Subarray Sum Equals K 108 | **Problem:** 109 | Given an array of integers and an integer `k`, return the total number of continuous subarrays whose sum equals `k`. 110 | 111 | **Input:** 112 | - Array: `[1, 1, 1]` 113 | - Target: `2` 114 | 115 | **Output:** 116 | - Result: `2` 117 | 118 | --- 119 | 120 | ### Task 10: Longest Consecutive Sequence 121 | **Problem:** 122 | Given an unsorted array of integers, find the length of the longest consecutive elements sequence. The algorithm should run in `O(n)` time complexity. 123 | 124 | **Input:** 125 | - Array: `[100, 4, 200, 1, 3, 2]` 126 | 127 | **Output:** 128 | - Result: `4` 129 | 130 | --- -------------------------------------------------------------------------------- /heap/README.md: -------------------------------------------------------------------------------- 1 | # Heap Data Structure in JavaScript 🚀 2 | 3 | ## 0-5 minutes: Check the Home Task 4 | - Review solutions. 5 | - Discuss any issues and common mistakes encountered. 6 | - Clarify doubts related to the home task. 7 | 8 | ### Key Points to Address: 9 | - If any of the students faced issues with basic concepts like **arrays**, **binary trees**, or **priority queues**, address those foundational concepts briefly before moving forward. 10 | - Explain the **Heap** data structure to everyone: 11 | - A **Heap** is a specialized binary tree-based data structure that satisfies the **heap property**: 12 | - In a **Max-Heap**, the value of each parent node is greater than or equal to the values of its children. 13 | - In a **Min-Heap**, the value of each parent node is less than or equal to the values of its children. 14 | - Heaps are commonly used in priority queues and algorithms like **Heap Sort**. 15 | 16 | ## 5-10 minutes: Introduction to Heap and its Key Operations 17 | - Explain the **Heap** data structure and its real-world analogy (like a pyramid where the largest or smallest value is at the top). 18 | - Discuss key operations: 19 | - **insert(value)**: Adds a value to the heap while maintaining the heap property. 20 | - **extractMax()** or **extractMin()**: Removes and returns the root value (the maximum or minimum value, depending on the type of heap). 21 | - **peek()**: Returns the root value without removing it. 22 | - **heapify()**: Ensures the heap property is maintained after an operation. 23 | 24 | ## 10-20 minutes: Implement a Min-Heap Class from Scratch 25 | - Guide students to implement a Min-Heap class in JavaScript. 26 | - The class should support the following methods: 27 | - `insert(value)` 28 | - `extractMin()` 29 | - `peek()` 30 | - `heapify()` 31 | 32 | Example: 33 | 34 | ```javascript 35 | class MinHeap { 36 | constructor() { 37 | this.heap = []; 38 | } 39 | 40 | // Returns the index of the parent 41 | getParentIndex(index) { 42 | return Math.floor((index - 1) / 2); 43 | } 44 | 45 | // Returns the index of the left child 46 | getLeftChildIndex(index) { 47 | return 2 * index + 1; 48 | } 49 | 50 | // Returns the index of the right child 51 | getRightChildIndex(index) { 52 | return 2 * index + 2; 53 | } 54 | 55 | // Swaps two elements in the heap 56 | swap(index1, index2) { 57 | [this.heap[index1], this.heap[index2]] = [this.heap[index2], this.heap[index1]]; 58 | } 59 | 60 | // Inserts a value into the heap 61 | insert(value) { 62 | this.heap.push(value); 63 | this.heapifyUp(); 64 | } 65 | 66 | // Moves the last element up to maintain the heap property 67 | heapifyUp() { 68 | let index = this.heap.length - 1; 69 | 70 | while ( 71 | index > 0 && 72 | this.heap[index] < this.heap[this.getParentIndex(index)] 73 | ) { 74 | this.swap(index, this.getParentIndex(index)); 75 | index = this.getParentIndex(index); 76 | } 77 | } 78 | 79 | // Extracts the minimum value (root) from the heap 80 | extractMin() { 81 | if (this.heap.length === 0) { 82 | return 'Heap is empty'; 83 | } 84 | if (this.heap.length === 1) { 85 | return this.heap.pop(); 86 | } 87 | 88 | const root = this.heap[0]; 89 | this.heap[0] = this.heap.pop(); 90 | this.heapifyDown(); 91 | return root; 92 | } 93 | 94 | // Moves the root down to maintain the heap property 95 | heapifyDown() { 96 | let index = 0; 97 | 98 | while (this.getLeftChildIndex(index) < this.heap.length) { 99 | let smallerChildIndex = this.getLeftChildIndex(index); 100 | 101 | if ( 102 | this.getRightChildIndex(index) < this.heap.length && 103 | this.heap[this.getRightChildIndex(index)] < this.heap[smallerChildIndex] 104 | ) { 105 | smallerChildIndex = this.getRightChildIndex(index); 106 | } 107 | 108 | if (this.heap[index] <= this.heap[smallerChildIndex]) { 109 | break; 110 | } 111 | 112 | this.swap(index, smallerChildIndex); 113 | index = smallerChildIndex; 114 | } 115 | } 116 | 117 | // Returns the minimum value (root) without removing it 118 | peek() { 119 | if (this.heap.length === 0) { 120 | return 'Heap is empty'; 121 | } 122 | return this.heap[0]; 123 | } 124 | } 125 | 126 | // Example usage: 127 | const minHeap = new MinHeap(); 128 | minHeap.insert(5); 129 | minHeap.insert(3); 130 | minHeap.insert(8); 131 | console.log(minHeap.peek()); // 3 132 | console.log(minHeap.extractMin()); // 3 133 | console.log(minHeap.peek()); // 5 134 | ``` 135 | 136 | ## 20-30 minutes: Task - Solve a Problem Using a Heap 137 | - Assign a task where students need to solve a problem using the Heap. 138 | - Example problem: Find the **kth smallest element** in an array using a Min-Heap. 139 | 140 | Example: 141 | 142 | ```javascript 143 | function findKthSmallest(arr, k) { 144 | const minHeap = new MinHeap(); 145 | 146 | arr.forEach(value => minHeap.insert(value)); 147 | 148 | for (let i = 1; i < k; i++) { 149 | minHeap.extractMin(); 150 | } 151 | 152 | return minHeap.peek(); 153 | } 154 | 155 | console.log(findKthSmallest([7, 10, 4, 3, 20, 15], 3)); // 7 156 | ``` 157 | 158 | ## 30-40 minutes: Home Task - Solve a Problem Using Heap from LeetCode 159 | - Provide a LeetCode problem that can be solved using the Heap data structure. 160 | - Students can work on this problem during the session or as homework. 161 | 162 | --- 163 | 164 | ## Connect with Me: 165 | - [LinkedIn - Vitalii Semianchuk](https://www.linkedin.com/in/vitalii-semianchuk-9812a786/) 166 | - [Telegram - @jsmentorfree](https://t.me/jsmentorfree) - We do a lot of free teaching on this channel! Join us to learn and grow in web development. 167 | - [Tiktok - @jsmentoring](https://www.tiktok.com/@jsmentoring) Everyday new videos 168 | - [Youtube - @jsmentor-uk](https://www.youtube.com/@jsmentor-uk) Mentor live streams 169 | - [Dev.to - fix2015](https://dev.to/fix2015) Javascript featured, live, experience -------------------------------------------------------------------------------- /heap/index.js: -------------------------------------------------------------------------------- 1 | class Heap { 2 | constructor(type = "max") { 3 | this.type = type; 4 | this.heap = []; 5 | } 6 | 7 | // Insert an element into the heap 8 | insert(value) { 9 | this.heap.push(value); 10 | this.heapifyUp(); 11 | } 12 | 13 | // Helper function to maintain the heap property after insertion 14 | heapifyUp() { 15 | let index = this.heap.length - 1; 16 | while (index > 0) { 17 | const parentIndex = Math.floor((index - 1) / 2); 18 | if (this.compare(this.heap[index], this.heap[parentIndex])) { 19 | [this.heap[index], this.heap[parentIndex]] = [this.heap[parentIndex], this.heap[index]]; 20 | index = parentIndex; 21 | } else { 22 | break; 23 | } 24 | } 25 | } 26 | 27 | // Extract the root element (max or min) 28 | extract() { 29 | if (this.size() === 0) return null; 30 | const root = this.heap[0]; 31 | const last = this.heap.pop(); 32 | if (this.size() > 0) { 33 | this.heap[0] = last; 34 | this.heapifyDown(); 35 | } 36 | return root; 37 | } 38 | 39 | // Helper function to maintain the heap property after extraction 40 | heapifyDown() { 41 | let index = 0; 42 | const length = this.heap.length; 43 | const leftChildIndex = (index * 2) + 1; 44 | const rightChildIndex = (index * 2) + 2; 45 | let swap = null; 46 | 47 | if (leftChildIndex < length) { 48 | if (this.compare(this.heap[leftChildIndex], this.heap[index])) { 49 | swap = leftChildIndex; 50 | } 51 | } 52 | if (rightChildIndex < length) { 53 | if (this.compare(this.heap[rightChildIndex], this.heap[swap || index])) { 54 | swap = rightChildIndex; 55 | } 56 | } 57 | if (swap === null) return; 58 | [this.heap[index], this.heap[swap]] = [this.heap[swap], this.heap[index]]; 59 | this.heapifyDown(); 60 | } 61 | 62 | // Compare two values based on the heap type 63 | compare(child, parent) { 64 | if (this.type === "max") { 65 | return child > parent; 66 | } 67 | return child < parent; 68 | } 69 | 70 | // Peek at the root element without removing it 71 | peek() { 72 | return this.heap[0]; 73 | } 74 | 75 | // Get the size of the heap 76 | size() { 77 | return this.heap.length; 78 | } 79 | } 80 | 81 | const maxHeap = new Heap("max"); 82 | 83 | // Insert elements into the heap 84 | maxHeap.insert(10); 85 | maxHeap.insert(20); 86 | maxHeap.insert(5); 87 | 88 | // Peek at the root element 89 | console.log(maxHeap.peek()); // Output: 20 90 | 91 | // Extract the root element (max) 92 | console.log(maxHeap.extract()); // Output: 20 93 | console.log(maxHeap.peek()); // Output: 10 94 | 95 | // Get the size of the heap 96 | console.log(maxHeap.size()); // Output: 2 97 | 98 | // Initialize a Min Heap 99 | const minHeap = new Heap("min"); 100 | 101 | // Insert elements into the min heap 102 | minHeap.insert(10); 103 | minHeap.insert(20); 104 | minHeap.insert(5); 105 | 106 | // Peek at the root element 107 | console.log(minHeap.peek()); // Output: 5 108 | 109 | // Extract the root element (min) 110 | console.log(minHeap.extract()); // Output: 5 111 | console.log(minHeap.peek()); // Output: 10 112 | -------------------------------------------------------------------------------- /heap/task.md: -------------------------------------------------------------------------------- 1 | ### Task 1: Kth Largest Element in an Array 2 | **Problem:** 3 | Given an integer array and an integer `k`, find the `k`th largest element in the array. Use a heap to efficiently find the `k`th largest element. 4 | 5 | **Input:** 6 | - Array: `[3, 2, 1, 5, 6, 4]` 7 | - `k = 2` 8 | 9 | **Output:** 10 | - Result: `5` 11 | 12 | --- 13 | 14 | ### Task 2: Merge K Sorted Lists 15 | **Problem:** 16 | Given `k` sorted linked lists, merge them into one sorted list. Use a heap to merge the lists efficiently. 17 | 18 | **Input:** 19 | - Lists: 20 | 1. `[1, 4, 5]` 21 | 2. `[1, 3, 4]` 22 | 3. `[2, 6]` 23 | 24 | **Output:** 25 | - Merged List: `[1, 1, 2, 3, 4, 4, 5, 6]` 26 | 27 | --- 28 | 29 | ### Task 3: Find Median from Data Stream 30 | **Problem:** 31 | Design a class that supports the following operations: 32 | - `addNum(num)` — Adds a number from the data stream. 33 | - `findMedian()` — Returns the median of all elements added so far. 34 | 35 | Use a heap to efficiently compute the median. 36 | 37 | **Input:** 38 | - Operations: 39 | 1. `addNum(1)` 40 | 2. `addNum(2)` 41 | 3. `findMedian()` 42 | 4. `addNum(3)` 43 | 5. `findMedian()` 44 | 45 | **Output:** 46 | - Result: 47 | 1. `null` (for `addNum`) 48 | 2. `1.5` (for `findMedian()`) 49 | 3. `2` (for `findMedian()`) 50 | 51 | --- 52 | 53 | ### Task 4: Top K Frequent Elements 54 | **Problem:** 55 | Given a non-empty array of integers, return the `k` most frequent elements. Use a heap to efficiently find the top `k` frequent elements. 56 | 57 | **Input:** 58 | - Array: `[1, 1, 1, 2, 2, 3]` 59 | - `k = 2` 60 | 61 | **Output:** 62 | - Result: `[1, 2]` 63 | 64 | --- 65 | 66 | ### Task 5: Sliding Window Maximum 67 | **Problem:** 68 | Given an array of integers `nums` and a sliding window of size `k`, find the maximum element in each sliding window as it moves from left to right. Use a heap to compute the maximum for each window efficiently. 69 | 70 | **Input:** 71 | - Array: `[1, 3, -1, -3, 5, 3, 6, 7]` 72 | - `k = 3` 73 | 74 | **Output:** 75 | - Result: `[3, 3, 5, 5, 6, 7]` 76 | 77 | --- 78 | 79 | ### Task 6: Connect Ropes with Minimum Cost 80 | **Problem:** 81 | Given `n` ropes with different lengths, connect the ropes into one rope. The cost of connecting two ropes is the sum of their lengths. Use a heap to minimize the total cost. 82 | 83 | **Input:** 84 | - Ropes: `[4, 3, 2, 6]` 85 | 86 | **Output:** 87 | - Result: `29` 88 | 89 | --- 90 | 91 | ### Task 7: Find the Kth Smallest Element in a Sorted Matrix 92 | **Problem:** 93 | Given an `n x n` matrix where each of the rows and columns is sorted in ascending order, find the `k`th smallest element in the matrix. Use a heap to find the `k`th smallest element efficiently. 94 | 95 | **Input:** 96 | - Matrix: 97 | ``` 98 | [ [1, 5, 9], [10, 11, 13], [12, 13, 15] ] 99 | ``` 100 | 101 | - `k = 8` 102 | 103 | **Output:** 104 | - Result: `13` 105 | 106 | --- 107 | 108 | ### Task 8: Huffman Encoding 109 | **Problem:** 110 | Given a string of characters, construct a Huffman tree for data compression. The tree should be constructed using a heap to minimize the total cost of encoding. 111 | 112 | **Input:** 113 | - String: `"aaabbc"` 114 | 115 | **Output:** 116 | - Huffman Codes: 117 | - `a: 0` 118 | - `b: 10` 119 | - `c: 11` 120 | 121 | --- 122 | 123 | ### Task 9: Top K Elements in a Stream 124 | **Problem:** 125 | Given a stream of integers, find the top `k` largest elements from the stream at any point in time. Use a heap to maintain the top `k` elements. 126 | 127 | **Input:** 128 | - Stream: `[3, 1, 4, 1, 5, 9, 2, 6, 5, 3]` 129 | - `k = 3` 130 | 131 | **Output:** 132 | - Result: `[5, 5, 6]` 133 | 134 | --- 135 | 136 | ### Task 10: Rearrange Characters in a String 137 | **Problem:** 138 | Given a string `s`, rearrange its characters such that no two adjacent characters are the same. Use a heap to rearrange the characters with the highest frequencies. 139 | 140 | **Input:** 141 | - String: `"aab"` 142 | 143 | **Output:** 144 | - Rearranged String: `"aba"` 145 | 146 | --- 147 | -------------------------------------------------------------------------------- /linked_list/README.md: -------------------------------------------------------------------------------- 1 | # Linked List Data Structure in JavaScript 🚀 2 | 3 | ## 0-5 minutes: Check the Home Task 4 | - Review solutions. 5 | - Discuss any issues and common mistakes encountered. 6 | - Clarify doubts related to the home task. 7 | 8 | ### Key Points to Address: 9 | - If any of the students faced issues with basic concepts like **arrays**, **queues**, or **stacks**, address those foundational concepts briefly before moving forward. 10 | - Explain the **Linked List** data structure to everyone: 11 | - A **Linked List** is a linear data structure where each element (called a node) contains: 12 | - **Data**: The value of the node. 13 | - **Next**: A pointer/reference to the next node in the sequence. 14 | - Unlike arrays, linked lists do not require contiguous memory and allow efficient insertion and deletion of elements. 15 | 16 | ## 5-10 minutes: Introduction to Linked List and its Key Operations 17 | - Explain the **Linked List** data structure and its real-world analogy (like a chain of connected links). 18 | - Discuss key operations: 19 | - **add(value)**: Adds a node with the given value to the end of the list. 20 | - **insertAt(index, value)**: Inserts a node with the given value at a specific position. 21 | - **remove(value)**: Removes the first node with the given value. 22 | - **search(value)**: Searches for a node with the given value. 23 | - **isEmpty()**: Checks if the list is empty. 24 | 25 | ## 10-20 minutes: Implement a Singly Linked List Class from Scratch 26 | - Guide students to implement a Singly Linked List class in JavaScript. 27 | - The class should support the following methods: 28 | - `add(value)` 29 | - `insertAt(index, value)` 30 | - `remove(value)` 31 | - `search(value)` 32 | - `isEmpty()` 33 | 34 | Example: 35 | 36 | ```javascript 37 | class Node { 38 | constructor(value) { 39 | this.value = value; 40 | this.next = null; 41 | } 42 | } 43 | 44 | class LinkedList { 45 | constructor() { 46 | this.head = null; 47 | this.size = 0; 48 | } 49 | 50 | // Adds a node to the end of the list 51 | add(value) { 52 | const newNode = new Node(value); 53 | if (!this.head) { 54 | this.head = newNode; 55 | } else { 56 | let current = this.head; 57 | while (current.next) { 58 | current = current.next; 59 | } 60 | current.next = newNode; 61 | } 62 | this.size++; 63 | } 64 | 65 | // Inserts a node at a specific index 66 | insertAt(index, value) { 67 | if (index < 0 || index > this.size) { 68 | return 'Invalid index'; 69 | } 70 | const newNode = new Node(value); 71 | if (index === 0) { 72 | newNode.next = this.head; 73 | this.head = newNode; 74 | } else { 75 | let current = this.head; 76 | let previous = null; 77 | let count = 0; 78 | 79 | while (count < index) { 80 | previous = current; 81 | current = current.next; 82 | count++; 83 | } 84 | newNode.next = current; 85 | previous.next = newNode; 86 | } 87 | this.size++; 88 | } 89 | 90 | // Removes the first occurrence of a value 91 | remove(value) { 92 | if (!this.head) { 93 | return 'List is empty'; 94 | } 95 | 96 | if (this.head.value === value) { 97 | this.head = this.head.next; 98 | this.size--; 99 | return; 100 | } 101 | 102 | let current = this.head; 103 | let previous = null; 104 | 105 | while (current && current.value !== value) { 106 | previous = current; 107 | current = current.next; 108 | } 109 | 110 | if (current) { 111 | previous.next = current.next; 112 | this.size--; 113 | } 114 | } 115 | 116 | // Searches for a value in the list 117 | search(value) { 118 | let current = this.head; 119 | 120 | while (current) { 121 | if (current.value === value) { 122 | return true; 123 | } 124 | current = current.next; 125 | } 126 | 127 | return false; 128 | } 129 | 130 | // Checks if the list is empty 131 | isEmpty() { 132 | return this.size === 0; 133 | } 134 | } 135 | 136 | // Example usage: 137 | const list = new LinkedList(); 138 | list.add(1); 139 | list.add(2); 140 | list.add(3); 141 | console.log(list.search(2)); // true 142 | list.remove(2); 143 | console.log(list.search(2)); // false 144 | console.log(list.isEmpty()); // false 145 | ``` 146 | 147 | ## 20-30 minutes: Task - Solve a Problem Using a Linked List 148 | - Assign a task where students need to solve a problem using the Linked List. 149 | - Example problem: Reverse a linked list. 150 | 151 | Example: 152 | 153 | ```javascript 154 | function reverseLinkedList(list) { 155 | let previous = null; 156 | let current = list.head; 157 | 158 | while (current) { 159 | const nextNode = current.next; 160 | current.next = previous; 161 | previous = current; 162 | current = nextNode; 163 | } 164 | 165 | list.head = previous; 166 | } 167 | 168 | // Example usage: 169 | reverseLinkedList(list); 170 | ``` 171 | 172 | ## 30-40 minutes: Home Task - Solve a Problem Using Linked List from LeetCode 173 | - Provide a LeetCode problem that can be solved using the Linked List data structure. 174 | - Students can work on this problem during the session or as homework. 175 | 176 | --- 177 | 178 | ## Connect with Me: 179 | - [LinkedIn - Vitalii Semianchuk](https://www.linkedin.com/in/vitalii-semianchuk-9812a786/) 180 | - [Telegram - @jsmentorfree](https://t.me/jsmentorfree) - We do a lot of free teaching on this channel! Join us to learn and grow in web development. 181 | - [Tiktok - @jsmentoring](https://www.tiktok.com/@jsmentoring) Everyday new videos 182 | - [Youtube - @jsmentor-uk](https://www.youtube.com/@jsmentor-uk) Mentor live streams 183 | - [Dev.to - fix2015](https://dev.to/fix2015) Javascript featured, live, experience -------------------------------------------------------------------------------- /linked_list/index.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(data) { 3 | this.data = data; 4 | this.next = null; 5 | } 6 | } 7 | 8 | class LinkedList { 9 | constructor() { 10 | this.head = null; 11 | this.size = 0; 12 | } 13 | 14 | // Insert a new node at the end of the list 15 | insert(data) { 16 | const newNode = new Node(data); 17 | if (this.head === null) { 18 | this.head = newNode; 19 | } else { 20 | let current = this.head; 21 | while (current.next !== null) { 22 | current = current.next; 23 | } 24 | current.next = newNode; 25 | } 26 | this.size++; 27 | } 28 | 29 | // Delete the first node containing the given data 30 | delete(data) { 31 | if (this.head === null) { 32 | return "List is empty!"; 33 | } 34 | if (this.head.data === data) { 35 | this.head = this.head.next; 36 | this.size--; 37 | return; 38 | } 39 | let current = this.head; 40 | while (current.next !== null && current.next.data !== data) { 41 | current = current.next; 42 | } 43 | if (current.next === null) { 44 | return "Data not found!"; 45 | } 46 | current.next = current.next.next; 47 | this.size--; 48 | } 49 | 50 | // Search for a node by its data 51 | search(data) { 52 | let current = this.head; 53 | while (current !== null) { 54 | if (current.data === data) { 55 | return true; 56 | } 57 | current = current.next; 58 | } 59 | return false; 60 | } 61 | 62 | // Traverse the list and print the data of each node 63 | traverse() { 64 | let current = this.head; 65 | while (current !== null) { 66 | console.log(current.data); 67 | current = current.next; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /linked_list/task.md: -------------------------------------------------------------------------------- 1 | ### Task 1: Reverse a Linked List 2 | **Problem:** 3 | Given the head of a singly linked list, reverse the list and return its head. 4 | 5 | **Input:** 6 | - List: `1 -> 2 -> 3 -> 4 -> 5` 7 | 8 | **Output:** 9 | - Reversed List: `5 -> 4 -> 3 -> 2 -> 1` 10 | 11 | --- 12 | 13 | ### Task 2: Detect Cycle in a Linked List 14 | **Problem:** 15 | Given a linked list, determine if it has a cycle in it. A cycle is present if a node’s next pointer points to one of the previous nodes in the list. 16 | 17 | **Input:** 18 | - List: `3 -> 2 -> 0 -> -4` (Cycle at node `2`) 19 | 20 | **Output:** 21 | - Result: `true` 22 | 23 | --- 24 | 25 | ### Task 3: Merge Two Sorted Linked Lists 26 | **Problem:** 27 | Given two sorted linked lists, merge them into one sorted list and return its head. 28 | 29 | **Input:** 30 | - List 1: `1 -> 2 -> 4` 31 | - List 2: `1 -> 3 -> 4` 32 | 33 | **Output:** 34 | - Merged List: `1 -> 1 -> 2 -> 3 -> 4 -> 4` 35 | 36 | --- 37 | 38 | ### Task 4: Remove N-th Node from End of List 39 | **Problem:** 40 | Given the head of a linked list, remove the n-th node from the end of the list and return its head. 41 | 42 | **Input:** 43 | - List: `1 -> 2 -> 3 -> 4 -> 5` 44 | - `n = 2` 45 | 46 | **Output:** 47 | - List after removal: `1 -> 2 -> 3 -> 5` 48 | 49 | --- 50 | 51 | ### Task 5: Find the Middle of a Linked List 52 | **Problem:** 53 | Given the head of a linked list, return the middle node of the list. If there are two middle nodes, return the second one. 54 | 55 | **Input:** 56 | - List: `1 -> 2 -> 3 -> 4 -> 5` 57 | 58 | **Output:** 59 | - Middle Node: `3` 60 | 61 | --- 62 | 63 | ### Task 6: Palindrome Linked List 64 | **Problem:** 65 | Given a singly linked list, determine if it is a palindrome. A palindrome is a list that reads the same forward and backward. 66 | 67 | **Input:** 68 | - List: `1 -> 2 -> 2 -> 1` 69 | 70 | **Output:** 71 | - Result: `true` 72 | 73 | --- 74 | 75 | ### Task 7: Remove Duplicates from Sorted Linked List 76 | **Problem:** 77 | Given a sorted linked list, delete all duplicates such that each element appears only once. 78 | 79 | **Input:** 80 | - List: `1 -> 1 -> 2 -> 3 -> 3` 81 | 82 | **Output:** 83 | - List after removal: `1 -> 2 -> 3` 84 | 85 | --- 86 | 87 | ### Task 8: Reorder List 88 | **Problem:** 89 | Given a singly linked list, reorder it so that it follows the pattern: `L0 → Ln → L1 → Ln-1 → L2 → Ln-2 → ...` 90 | 91 | **Input:** 92 | - List: `1 -> 2 -> 3 -> 4 -> 5` 93 | 94 | **Output:** 95 | - Reordered List: `1 -> 5 -> 2 -> 4 -> 3` 96 | 97 | --- 98 | 99 | ### Task 9: Intersection of Two Linked Lists 100 | **Problem:** 101 | Given the heads of two singly linked lists, determine if the two lists intersect. If they do, return the node where the intersection begins. Otherwise, return `null`. 102 | 103 | **Input:** 104 | - List 1: `4 -> 1 -> 8 -> 4 -> 5` 105 | - List 2: `5 -> 6 -> 1 -> 8 -> 4 -> 5` 106 | 107 | **Output:** 108 | - Intersection Node: `8` 109 | 110 | --- 111 | 112 | ### Task 10: Flatten a Linked List 113 | **Problem:** 114 | Given a linked list where each node may have a child pointer in addition to the next pointer, flatten the list so that all the nodes appear in a single-level linked list. 115 | 116 | **Input:** 117 | - List: `1 -> 2 -> 3 -> 4 -> 5 -> 6` with children at nodes `3` and `5` 118 | 119 | **Output:** 120 | - Flattened List: `1 -> 2 -> 3 -> 7 -> 8 -> 4 -> 5 -> 9 -> 10 -> 6` 121 | 122 | --- 123 | -------------------------------------------------------------------------------- /priority_queue/README.md: -------------------------------------------------------------------------------- 1 | # Priority Queue Data Structure in JavaScript 🚀 2 | 3 | ## 0-5 minutes: Check the Home Task 4 | - Review solutions. 5 | - Discuss any issues and common mistakes encountered. 6 | - Clarify doubts related to the home task. 7 | 8 | ### Key Points to Address: 9 | - If any of the students faced issues with basic concepts like **arrays**, **linked lists**, or **queues**, address those foundational concepts briefly before moving forward. 10 | - Explain the **Priority Queue** data structure to everyone: 11 | - A **Priority Queue** is a special type of queue where each element is associated with a priority. 12 | - Elements with higher priority are dequeued before elements with lower priority, regardless of their insertion order. 13 | - The key operations are: 14 | - **enqueue(element, priority)**: Adds an element to the queue with a given priority. 15 | - **dequeue()**: Removes and returns the element with the highest priority. 16 | - **peek()**: Returns the element with the highest priority without removing it. 17 | - **isEmpty()**: Checks if the queue is empty. 18 | 19 | ## 5-10 minutes: Introduction to Priority Queue and its Key Operations 20 | - Explain the **Priority Queue** data structure and its real-world analogy (like a hospital emergency room). 21 | - Discuss key operations: 22 | - **enqueue(element, priority)**: Adds an element to the queue with a given priority. 23 | - **dequeue()**: Removes and returns the element with the highest priority. 24 | - **peek()**: Returns the element with the highest priority without removing it. 25 | - **isEmpty()**: Checks if the queue is empty. 26 | 27 | ## 10-20 minutes: Implement a Priority Queue Class from Scratch 28 | - Guide students to implement a Priority Queue class in JavaScript. 29 | - The class should support the following methods: 30 | - `enqueue(element, priority)` 31 | - `dequeue()` 32 | - `peek()` 33 | - `isEmpty()` 34 | 35 | Example: 36 | 37 | ```javascript 38 | class PriorityQueue { 39 | constructor() { 40 | this.items = []; 41 | } 42 | 43 | // Adds an element with a priority 44 | enqueue(element, priority) { 45 | const queueElement = { element, priority }; 46 | let added = false; 47 | 48 | for (let i = 0; i < this.items.length; i++) { 49 | if (queueElement.priority < this.items[i].priority) { 50 | this.items.splice(i, 0, queueElement); 51 | added = true; 52 | break; 53 | } 54 | } 55 | 56 | if (!added) { 57 | this.items.push(queueElement); 58 | } 59 | } 60 | 61 | // Removes and returns the element with the highest priority 62 | dequeue() { 63 | if (this.isEmpty()) { 64 | return 'Priority Queue is empty'; 65 | } 66 | return this.items.shift(); 67 | } 68 | 69 | // Returns the element with the highest priority without removing it 70 | peek() { 71 | if (this.isEmpty()) { 72 | return 'Priority Queue is empty'; 73 | } 74 | return this.items[0]; 75 | } 76 | 77 | // Checks if the queue is empty 78 | isEmpty() { 79 | return this.items.length === 0; 80 | } 81 | } 82 | 83 | // Example usage: 84 | const pq = new PriorityQueue(); 85 | pq.enqueue('Patient A', 2); 86 | pq.enqueue('Patient B', 1); 87 | pq.enqueue('Patient C', 3); 88 | 89 | console.log(pq.dequeue()); // { element: 'Patient B', priority: 1 } 90 | console.log(pq.peek()); // { element: 'Patient A', priority: 2 } 91 | console.log(pq.isEmpty()); // false 92 | ``` 93 | 94 | ## 20-30 minutes: Task - Solve a Problem Using a Priority Queue 95 | - Assign a task where students need to solve a problem using the Priority Queue. 96 | - Example problem: Simulate a system that handles customer service requests with different priority levels. 97 | 98 | Example: 99 | 100 | ```javascript 101 | function customerSupportSystem(requests) { 102 | const pq = new PriorityQueue(); 103 | 104 | requests.forEach(request => { 105 | pq.enqueue(request.name, request.priority); 106 | }); 107 | 108 | while (!pq.isEmpty()) { 109 | const served = pq.dequeue(); 110 | console.log(`Serving: ${served.element} with priority ${served.priority}`); 111 | } 112 | } 113 | 114 | const requests = [ 115 | { name: 'Request A', priority: 3 }, 116 | { name: 'Request B', priority: 1 }, 117 | { name: 'Request C', priority: 2 } 118 | ]; 119 | 120 | customerSupportSystem(requests); 121 | ``` 122 | 123 | ## 30-40 minutes: Home Task - Solve a Problem Using Priority Queue from LeetCode 124 | - Provide a LeetCode problem that can be solved using the Priority Queue data structure. 125 | - Students can work on this problem during the session or as homework. 126 | 127 | --- 128 | 129 | ## Connect with Me: 130 | - [LinkedIn - Vitalii Semianchuk](https://www.linkedin.com/in/vitalii-semianchuk-9812a786/) 131 | - [Telegram - @jsmentorfree](https://t.me/jsmentorfree) - We do a lot of free teaching on this channel! Join us to learn and grow in web development. 132 | - [Tiktok - @jsmentoring](https://www.tiktok.com/@jsmentoring) Everyday new videos 133 | - [Youtube - @jsmentor-uk](https://www.youtube.com/@jsmentor-uk) Mentor live streams 134 | - [Dev.to - fix2015](https://dev.to/fix2015) Javascript featured, live, experience -------------------------------------------------------------------------------- /priority_queue/index.js: -------------------------------------------------------------------------------- 1 | class PriorityQueue { 2 | constructor() { 3 | this.queue = []; 4 | } 5 | 6 | // Add an element to the queue with a given priority 7 | enqueue(element, priority) { 8 | const item = { element, priority }; 9 | if (this.isEmpty()) { 10 | this.queue.push(item); 11 | } else { 12 | let added = false; 13 | for (let i = 0; i < this.queue.length; i++) { 14 | if (item.priority > this.queue[i].priority) { 15 | this.queue.splice(i, 0, item); 16 | added = true; 17 | break; 18 | } 19 | } 20 | if (!added) { 21 | this.queue.push(item); 22 | } 23 | } 24 | } 25 | 26 | // Remove and return the element with the highest priority 27 | dequeue() { 28 | if (this.isEmpty()) { 29 | return "Queue is empty!"; 30 | } 31 | return this.queue.shift(); 32 | } 33 | 34 | // View the element with the highest priority without removing it 35 | peek() { 36 | if (this.isEmpty()) { 37 | return "Queue is empty!"; 38 | } 39 | return this.queue[0]; 40 | } 41 | 42 | // Check if the queue is empty 43 | isEmpty() { 44 | return this.queue.length === 0; 45 | } 46 | 47 | // Get the size of the queue 48 | size() { 49 | return this.queue.length; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /priority_queue/task.md: -------------------------------------------------------------------------------- 1 | ### Task 1: Kth Largest Element in an Array 2 | **Problem:** 3 | Given an integer array and an integer `k`, find the `k`th largest element in the array. Implement the solution using a priority queue (min-heap). 4 | 5 | **Input:** 6 | - Array: `[3, 2, 1, 5, 6, 4]` 7 | - `k = 2` 8 | 9 | **Output:** 10 | - Result: `5` 11 | 12 | --- 13 | 14 | ### Task 2: Merge K Sorted Lists 15 | **Problem:** 16 | Given `k` sorted linked lists, merge them into one sorted list. Use a priority queue to efficiently merge the lists. 17 | 18 | **Input:** 19 | - Lists: 20 | 1. `[1, 4, 5]` 21 | 2. `[1, 3, 4]` 22 | 3. `[2, 6]` 23 | 24 | **Output:** 25 | - Merged list: `[1, 1, 2, 3, 4, 4, 5, 6]` 26 | 27 | --- 28 | 29 | ### Task 3: Find Median from Data Stream 30 | **Problem:** 31 | Design a class that supports the following operations: 32 | - `addNum(num)` — Adds a number from the data stream. 33 | - `findMedian()` — Returns the median of all elements added so far. 34 | 35 | The class should maintain the median in an efficient way using a priority queue (min-heap and max-heap). 36 | 37 | **Input:** 38 | - Operations: 39 | 1. `addNum(1)` 40 | 2. `addNum(2)` 41 | 3. `findMedian()` 42 | 4. `addNum(3)` 43 | 5. `findMedian()` 44 | 45 | **Output:** 46 | - Result: 47 | 1. `null` (for `addNum`) 48 | 2. `1.5` (for `findMedian()`) 49 | 3. `2` (for `findMedian()`) 50 | 51 | --- 52 | 53 | ### Task 4: Top K Frequent Elements 54 | **Problem:** 55 | Given a non-empty array of integers, return the `k` most frequent elements. Implement the solution using a priority queue (min-heap). 56 | 57 | **Input:** 58 | - Array: `[1, 1, 1, 2, 2, 3]` 59 | - `k = 2` 60 | 61 | **Output:** 62 | - Result: `[1, 2]` 63 | 64 | --- 65 | 66 | ### Task 5: Reorganize String 67 | **Problem:** 68 | Given a string `s`, rearrange the characters of the string so that no two adjacent characters are the same. Return the rearranged string or an empty string if it is not possible. 69 | 70 | **Input:** 71 | - String: `"aab"` 72 | 73 | **Output:** 74 | - Result: `"aba"` 75 | 76 | --- 77 | 78 | ### Task 6: Connect Ropes with Minimum Cost 79 | **Problem:** 80 | Given `n` ropes with different lengths, connect the ropes into one rope. The cost of connecting two ropes is the sum of their lengths. Implement the solution using a priority queue (min-heap) to minimize the total cost. 81 | 82 | **Input:** 83 | - Ropes: `[4, 3, 2, 6]` 84 | 85 | **Output:** 86 | - Result: `29` 87 | 88 | --- 89 | 90 | ### Task 7: Sliding Window Maximum 91 | **Problem:** 92 | Given an array of integers `nums` and a sliding window of size `k`, find the maximum element in each sliding window as it moves from left to right. 93 | 94 | **Input:** 95 | - Array: `[1, 3, -1, -3, 5, 3, 6, 7]` 96 | - `k = 3` 97 | 98 | **Output:** 99 | - Result: `[3, 3, 5, 5, 6, 7]` 100 | 101 | --- 102 | -------------------------------------------------------------------------------- /queue/README.md: -------------------------------------------------------------------------------- 1 | # Queue Data Structure in JavaScript 🚀 2 | 3 | ### Key Points to Address: 4 | - If any of the students faced issues with basic concepts like **arrays**, **linked lists**, or **stacks**, address those foundational concepts briefly before moving forward. 5 | - Explain the **Queue** data structure to everyone: 6 | - A **Queue** is a **First-In, First-Out (FIFO)** structure. 7 | - It works similarly to a line in a bank or supermarket where the first person in line is the first to be served. 8 | - The key operations are: 9 | - **enqueue(item)**: Adds an item to the back of the queue. 10 | - **dequeue()**: Removes the item from the front of the queue. 11 | - **peek()**: Views the item at the front without removing it. 12 | - **isEmpty()**: Checks if the queue is empty. 13 | 14 | ## 5-10 minutes: Introduction to Queue and its Key Operations 15 | - Explain the **Queue** data structure and its real-world analogy (like a queue in a bank). 16 | - Discuss key operations: 17 | - **enqueue(item)**: Adds an item to the back of the queue. 18 | - **dequeue()**: Removes an item from the front of the queue. 19 | - **peek()**: Returns the item at the front of the queue without removing it. 20 | - **isEmpty()**: Checks if the queue is empty. 21 | 22 | ## 10-20 minutes: Implement a Queue Class from Scratch 23 | - Guide students to implement a Queue class in JavaScript. 24 | - The class should support the following methods: 25 | - `enqueue(item)` 26 | - `dequeue()` 27 | - `peek()` 28 | - `isEmpty()` 29 | 30 | Example: 31 | 32 | ```javascript 33 | class Queue { 34 | constructor() { 35 | this.items = []; 36 | } 37 | 38 | // Adds an item to the back of the queue 39 | enqueue(item) { 40 | this.items.push(item); 41 | } 42 | 43 | // Removes an item from the front of the queue 44 | dequeue() { 45 | if (this.isEmpty()) { 46 | return 'Queue is empty'; 47 | } 48 | return this.items.shift(); // Removes the first item 49 | } 50 | 51 | // Returns the item at the front without removing it 52 | peek() { 53 | if (this.isEmpty()) { 54 | return 'Queue is empty'; 55 | } 56 | return this.items[0]; // The first item in the queue 57 | } 58 | 59 | // Checks if the queue is empty 60 | isEmpty() { 61 | return this.items.length === 0; 62 | } 63 | } 64 | ``` 65 | 66 | ## 20-30 minutes: Task - Implement a Queue-based Solution for a Problem 67 | - Assign a task where students need to solve a problem using the Queue. 68 | - Example problem: Implement a system to simulate the handling of requests in a print queue. 69 | 70 | ## 30-40 minutes: Home Task - Solve a Problem Using Queue from LeetCode 71 | - Provide a LeetCode problem that can be solved using the Queue data structure. 72 | - Students can work on this problem during the session or as homework. 73 | 74 | --- 75 | 76 | ## Connect with Me: 77 | - [LinkedIn - Vitalii Semianchuk](https://www.linkedin.com/in/vitalii-semianchuk-9812a786/) 78 | - [Telegram - @jsmentorfree](https://t.me/jsmentorfree) - We do a lot of free teaching on this channel! Join us to learn and grow in web development. 79 | - [Tiktok - @jsmentoring](https://www.tiktok.com/@jsmentoring) Everyday new videos 80 | - [Youtube - @jsmentor-uk](https://www.youtube.com/@jsmentor-uk) Mentor live streams 81 | - [Dev.to - fix2015](https://dev.to/fix2015) Javascript featured, live, experience -------------------------------------------------------------------------------- /queue/index.js: -------------------------------------------------------------------------------- 1 | class Queue { 2 | constructor() { 3 | this.items = []; // Initialize an empty array 4 | } 5 | 6 | // Add an item to the queue 7 | enqueue(element) { 8 | this.items.push(element); 9 | } 10 | 11 | // Remove and return the front item 12 | dequeue() { 13 | if (this.isEmpty()) { 14 | return "Queue is empty!"; 15 | } 16 | return this.items.shift(); 17 | } 18 | 19 | // Check if the queue is empty 20 | isEmpty() { 21 | return this.items.length === 0; 22 | } 23 | 24 | // Peek at the front item without removing it 25 | peek() { 26 | if (this.isEmpty()) { 27 | return "Queue is empty!"; 28 | } 29 | return this.items[0]; 30 | } 31 | 32 | // Get the size of the queue 33 | size() { 34 | return this.items.length; 35 | } 36 | } 37 | 38 | const queue = new Queue(); 39 | queue.enqueue("Task 1"); 40 | queue.enqueue("Task 2"); 41 | console.log(queue.peek()); // Task 1 42 | console.log(queue.dequeue()); // Task 1 43 | console.log(queue.isEmpty()); // false 44 | -------------------------------------------------------------------------------- /queue/task.js: -------------------------------------------------------------------------------- 1 | class Queue { 2 | constructor() { 3 | this.items = []; 4 | } 5 | 6 | // Add an item to the queue 7 | enqueue(element) { 8 | this.items.push(element); 9 | } 10 | 11 | // Remove and return the front item 12 | dequeue() { 13 | if (this.isEmpty()) { 14 | return "Queue is empty!"; 15 | } 16 | return this.items.shift(); 17 | } 18 | 19 | // Check if the queue is empty 20 | isEmpty() { 21 | return this.items.length === 0; 22 | } 23 | 24 | // Peek at the front item without removing it 25 | peek() { 26 | if (this.isEmpty()) { 27 | return "Queue is empty!"; 28 | } 29 | return this.items[0]; 30 | } 31 | 32 | // Get the size of the queue 33 | size() { 34 | return this.items.length; 35 | } 36 | } 37 | 38 | function processTasks(taskList) { 39 | const taskQueue = new Queue(); 40 | 41 | // Add tasks to the queue 42 | for (const task of taskList) { 43 | taskQueue.enqueue(task); 44 | } 45 | 46 | // Process tasks 47 | while (!taskQueue.isEmpty()) { 48 | const currentTask = taskQueue.dequeue(); 49 | console.log(`Processing ${currentTask.name} (Duration: ${currentTask.duration})`); 50 | } 51 | 52 | console.log("All tasks have been processed!"); 53 | } 54 | 55 | // Test cases 56 | const tasks = [ 57 | { name: "Task1", duration: 3 }, 58 | { name: "Task2", duration: 2 }, 59 | { name: "Task3", duration: 1 }, 60 | ]; 61 | 62 | processTasks(tasks); 63 | -------------------------------------------------------------------------------- /queue/task.md: -------------------------------------------------------------------------------- 1 | ### Task 1: Implement a Queue Using Two Stacks 2 | **Problem:** 3 | Design a queue that supports the following operations using two stacks: 4 | - `enqueue(x)` — Push element `x` to the back of the queue. 5 | - `dequeue()` — Removes the element from the front of the queue. 6 | - `peek()` — Get the front element. 7 | - `empty()` — Return whether the queue is empty. 8 | 9 | **Input:** 10 | - Operations: 11 | 1. `enqueue(1)` 12 | 2. `enqueue(2)` 13 | 3. `dequeue()` 14 | 4. `peek()` 15 | 5. `empty()` 16 | 17 | **Output:** 18 | - Result: 19 | 1. `null` (for `enqueue` operations) 20 | 2. `1` (for `dequeue()`) 21 | 3. `2` (for `peek()`) 22 | 4. `false` (for `empty()`) 23 | 24 | --- 25 | 26 | ### Task 2: Circular Queue 27 | **Problem:** 28 | Implement a circular queue with the following operations: 29 | - `enqueue(x)` — Adds an element to the queue. 30 | - `dequeue()` — Removes an element from the queue. 31 | - `front()` — Get the front element. 32 | - `rear()` — Get the last element. 33 | - `isFull()` — Check if the queue is full. 34 | - `isEmpty()` — Check if the queue is empty. 35 | 36 | **Input:** 37 | - Operations: 38 | 1. `enqueue(1)` 39 | 2. `enqueue(2)` 40 | 3. `enqueue(3)` 41 | 4. `dequeue()` 42 | 5. `front()` 43 | 44 | **Output:** 45 | - Result: 46 | 1. `null` (for `enqueue` operations) 47 | 2. `1` (for `dequeue()`) 48 | 3. `2` (for `front()`) 49 | 50 | --- 51 | 52 | ### Task 3: Reverse First K Elements of Queue 53 | **Problem:** 54 | Given a queue, reverse the first `k` elements of the queue. The remaining elements should be in the same order. 55 | 56 | **Input:** 57 | - Queue: `[1, 2, 3, 4, 5]` 58 | - `k = 3` 59 | 60 | **Output:** 61 | - Result: `[3, 2, 1, 4, 5]` 62 | 63 | --- 64 | 65 | ### Task 4: Moving Average from Data Stream 66 | **Problem:** 67 | Design a class that computes the moving average of the last `n` elements from a stream of data. Implement the `next(val)` method that computes the moving average of the stream as new elements are added. 68 | 69 | **Input:** 70 | - Initialize moving average with `n = 3`. 71 | - Add values: `next(1)`, `next(10)`, `next(3)`, `next(5)` 72 | 73 | **Output:** 74 | - Result: 75 | 1. `next(1)` → `1.0` 76 | 2. `next(10)` → `5.5` 77 | 3. `next(3)` → `4.66667` 78 | 4. `next(5)` → `6.0` 79 | 80 | --- 81 | 82 | ### Task 5: Generate Binary Numbers from 1 to N 83 | **Problem:** 84 | Given an integer `n`, generate all binary numbers from 1 to `n` using a queue. The queue should help generate the binary numbers level by level. 85 | 86 | **Input:** 87 | - `n = 5` 88 | 89 | **Output:** 90 | - Result: `["1", "10", "11", "100", "101"]` 91 | 92 | --- 93 | 94 | ### Task 6: Queue Reconstruction by Height 95 | **Problem:** 96 | Suppose you have a queue of people, and each person is represented by a pair of integers `(h, k)` where `h` is the height of the person, and `k` is the number of people in front of this person who have a height greater than or equal to `h`. Write a function to reconstruct the queue. 97 | 98 | **Input:** 99 | - Array of pairs: `[[7, 0], [4, 4], [7, 1], [5, 0], [6, 1], [5, 2]]` 100 | 101 | **Output:** 102 | - Result: `[[5, 0], [5, 2], [6, 1], [7, 0], [7, 1], [4, 4]]` 103 | 104 | --- 105 | -------------------------------------------------------------------------------- /set/README.md: -------------------------------------------------------------------------------- 1 | # Set Data Structure in JavaScript 🚀 2 | 3 | ## 0-5 minutes: Check the Home Task from Day 1 4 | - Review solutions from Day 1. 5 | - Discuss any issues and common mistakes encountered. 6 | - Clarify doubts related to the home task. 7 | 8 | ### Key Points to Address: 9 | - If any of the students faced issues with basic concepts like **arrays**, **linked lists**, or **stacks**, address those foundational concepts briefly before moving forward. 10 | - Explain the **Set** data structure to everyone: 11 | - A **Set** is a collection of unique values where duplicate elements are not allowed. 12 | - It is useful for operations like finding unique items, union, intersection, and difference between collections. 13 | - The key operations are: 14 | - **add(value)**: Adds a value to the set. 15 | - **delete(value)**: Removes a value from the set. 16 | - **has(value)**: Checks if a value exists in the set. 17 | - **clear()**: Removes all elements from the set. 18 | - **size**: Returns the number of elements in the set. 19 | 20 | ## 5-10 minutes: Introduction to Set and its Key Operations 21 | - Explain the **Set** data structure and its real-world analogy (like a collection of unique stamps or coins). 22 | - Discuss key operations: 23 | - **add(value)**: Adds a value to the set. 24 | - **delete(value)**: Removes a value from the set. 25 | - **has(value)**: Checks if a value exists in the set. 26 | - **clear()**: Removes all elements from the set. 27 | - **size**: Returns the number of elements in the set. 28 | 29 | ## 10-20 minutes: Implement a Set-Like Class from Scratch 30 | - Guide students to implement a Set-like class in JavaScript. 31 | - The class should support the following methods: 32 | - `add(value)` 33 | - `delete(value)` 34 | - `has(value)` 35 | - `clear()` 36 | - `size` 37 | 38 | Example: 39 | 40 | ```javascript 41 | class MySet { 42 | constructor() { 43 | this.items = {}; 44 | } 45 | 46 | add(value) { 47 | if (!this.has(value)) { 48 | this.items[value] = true; 49 | } 50 | } 51 | 52 | delete(value) { 53 | if (this.has(value)) { 54 | delete this.items[value]; 55 | } 56 | } 57 | 58 | has(value) { 59 | return this.items.hasOwnProperty(value); 60 | } 61 | 62 | clear() { 63 | this.items = {}; 64 | } 65 | 66 | get size() { 67 | return Object.keys(this.items).length; 68 | } 69 | } 70 | 71 | // Example usage: 72 | const set = new MySet(); 73 | set.add(1); 74 | set.add(2); 75 | set.add(2); // Duplicate, won't be added 76 | console.log(set.has(1)); // true 77 | console.log(set.size); // 2 78 | set.delete(1); 79 | console.log(set.has(1)); // false 80 | ``` 81 | 82 | ## 20-30 minutes: Task - Solve a Problem Using a Set 83 | - Assign a task where students need to solve a problem using the Set. 84 | - Example problem: Write a function that removes duplicate values from an array using a Set. 85 | 86 | Example: 87 | 88 | ```javascript 89 | function removeDuplicates(arr) { 90 | return [...new Set(arr)]; 91 | } 92 | 93 | console.log(removeDuplicates([1, 2, 2, 3, 4, 4])); // [1, 2, 3, 4] 94 | ``` 95 | 96 | ## 30-40 minutes: Home Task - Solve a Problem Using Set from LeetCode 97 | - Provide a LeetCode problem that can be solved using the Set data structure. 98 | - Students can work on this problem during the session or as homework. 99 | 100 | --- 101 | 102 | ## Connect with Me: 103 | - [LinkedIn - Vitalii Semianchuk](https://www.linkedin.com/in/vitalii-semianchuk-9812a786/) 104 | - [Telegram - @jsmentorfree](https://t.me/jsmentorfree) - We do a lot of free teaching on this channel! Join us to learn and grow in web development. 105 | - [Tiktok - @jsmentoring](https://www.tiktok.com/@jsmentoring) Everyday new videos 106 | - [Youtube - @jsmentor-uk](https://www.youtube.com/@jsmentor-uk) Mentor live streams 107 | - [Dev.to - fix2015](https://dev.to/fix2015) Javascript featured, live, experience -------------------------------------------------------------------------------- /set/index.js: -------------------------------------------------------------------------------- 1 | class Set { 2 | constructor() { 3 | this.items = {}; 4 | } 5 | 6 | // Add an element to the set 7 | add(element) { 8 | if (!this.has(element)) { 9 | this.items[element] = element; 10 | } 11 | } 12 | 13 | // Remove an element from the set 14 | delete(element) { 15 | if (this.has(element)) { 16 | delete this.items[element]; 17 | } 18 | } 19 | 20 | // Check if an element exists in the set 21 | has(element) { 22 | return this.items.hasOwnProperty(element); 23 | } 24 | 25 | // Get the size of the set 26 | size() { 27 | return Object.keys(this.items).length; 28 | } 29 | 30 | // Clear all elements from the set 31 | clear() { 32 | this.items = {}; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /set/task.md: -------------------------------------------------------------------------------- 1 | ### Task 1: Unique Elements in an Array 2 | **Problem:** 3 | Given an array of integers, write a function to determine if the array contains any duplicates. The function should return `true` if any value appears at least twice, and `false` if every element is distinct. 4 | 5 | **Input:** 6 | - Array: `[1, 2, 3, 4, 5, 1]` 7 | 8 | **Output:** 9 | - Result: `true` 10 | 11 | --- 12 | 13 | ### Task 2: Intersection of Two Arrays 14 | **Problem:** 15 | Given two arrays, write a function to compute their intersection. Each element in the result must appear as many times as it shows in both arrays. The result can be returned in any order. 16 | 17 | **Input:** 18 | - Array 1: `[1, 2, 2, 1]` 19 | - Array 2: `[2, 2]` 20 | 21 | **Output:** 22 | - Result: `[2, 2]` 23 | 24 | --- 25 | 26 | ### Task 3: Find the Union of Two Arrays 27 | **Problem:** 28 | Given two arrays, return the union of the arrays. Each element in the result must be unique, even if it appears multiple times in the input arrays. 29 | 30 | **Input:** 31 | - Array 1: `[1, 2, 2, 1]` 32 | - Array 2: `[2, 3, 4]` 33 | 34 | **Output:** 35 | - Result: `[1, 2, 3, 4]` 36 | 37 | --- 38 | 39 | ### Task 4: Subset of a Set 40 | **Problem:** 41 | Given a set of integers, return all possible subsets (the power set). The solution should include the empty set and the set itself. 42 | 43 | **Input:** 44 | - Set: `[1, 2, 3]` 45 | 46 | **Output:** 47 | - Result: `[[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]` 48 | 49 | --- 50 | 51 | ### Task 5: Check if Two Sets Are Disjoint 52 | **Problem:** 53 | Given two sets of integers, determine if they are disjoint. Two sets are disjoint if they do not have any common elements. 54 | 55 | **Input:** 56 | - Set 1: `{1, 2, 3}` 57 | - Set 2: `{4, 5, 6}` 58 | 59 | **Output:** 60 | - Result: `true` 61 | 62 | --- 63 | 64 | ### Task 6: Find the Symmetric Difference 65 | **Problem:** 66 | Given two sets of integers, return the symmetric difference. The symmetric difference is the set of elements that are in either of the sets, but not in their intersection. 67 | 68 | **Input:** 69 | - Set 1: `{1, 2, 3}` 70 | - Set 2: `{3, 4, 5}` 71 | 72 | **Output:** 73 | - Result: `[1, 2, 4, 5]` 74 | 75 | --- 76 | -------------------------------------------------------------------------------- /stack/README.md: -------------------------------------------------------------------------------- 1 | # Stack Data Structure in JavaScript 🚀 2 | 3 | ## 0-5 minutes: Check the Home Task 4 | - Review solutions. 5 | - Discuss any issues and common mistakes encountered. 6 | - Clarify doubts related to the home task. 7 | 8 | ### Key Points to Address: 9 | - If any of the students faced issues with basic concepts like **arrays**, **linked lists**, or **queues**, address those foundational concepts briefly before moving forward. 10 | - Explain the **Stack** data structure to everyone: 11 | - A **Stack** is a **Last-In, First-Out (LIFO)** structure. 12 | - It works similarly to a stack of plates: the last plate added is the first one to be removed. 13 | - The key operations are: 14 | - **push(item)**: Adds an item to the top of the stack. 15 | - **pop()**: Removes the item from the top of the stack. 16 | - **peek()**: Views the item at the top without removing it. 17 | - **isEmpty()**: Checks if the stack is empty. 18 | 19 | ## 5-10 minutes: Introduction to Stack and its Key Operations 20 | - Explain the **Stack** data structure and its real-world analogy (like a stack of plates). 21 | - Discuss key operations: 22 | - **push(item)**: Adds an item to the top of the stack. 23 | - **pop()**: Removes an item from the top of the stack. 24 | - **peek()**: Returns the item at the top of the stack without removing it. 25 | - **isEmpty()**: Checks if the stack is empty. 26 | 27 | ## 10-20 minutes: Implement a Stack Class from Scratch 28 | - Guide students to implement a Stack class in JavaScript. 29 | - The class should support the following methods: 30 | - `push(item)` 31 | - `pop()` 32 | - `peek()` 33 | - `isEmpty()` 34 | 35 | Example: 36 | 37 | ```javascript 38 | class Stack { 39 | constructor() { 40 | this.items = []; 41 | } 42 | 43 | // Adds an item to the top of the stack 44 | push(item) { 45 | this.items.push(item); 46 | } 47 | 48 | // Removes the item from the top of the stack 49 | pop() { 50 | if (this.isEmpty()) { 51 | return 'Stack is empty'; 52 | } 53 | return this.items.pop(); // Removes the last item 54 | } 55 | 56 | // Returns the item at the top without removing it 57 | peek() { 58 | if (this.isEmpty()) { 59 | return 'Stack is empty'; 60 | } 61 | return this.items[this.items.length - 1]; // The last item in the stack 62 | } 63 | 64 | // Checks if the stack is empty 65 | isEmpty() { 66 | return this.items.length === 0; 67 | } 68 | } 69 | ``` 70 | 71 | ## 20-30 minutes: Task - Implement a Stack-based Solution for a Problem 72 | - Assign a task where students need to solve a problem using the Stack. 73 | - Example problem: Implement a function to reverse a string using a Stack. 74 | 75 | ## 30-40 minutes: Home Task - Solve a Problem Using Stack from LeetCode 76 | - Provide a LeetCode problem that can be solved using the Stack data structure. 77 | - Students can work on this problem during the session or as homework. 78 | 79 | --- 80 | 81 | ## Connect with Me: 82 | - [LinkedIn - Vitalii Semianchuk](https://www.linkedin.com/in/vitalii-semianchuk-9812a786/) 83 | - [Telegram - @jsmentorfree](https://t.me/jsmentorfree) - We do a lot of free teaching on this channel! Join us to learn and grow in web development. 84 | - [Tiktok - @jsmentoring](https://www.tiktok.com/@jsmentoring) Everyday new videos 85 | - [Youtube - @jsmentor-uk](https://www.youtube.com/@jsmentor-uk) Mentor live streams 86 | - [Dev.to - fix2015](https://dev.to/fix2015) Javascript featured, live, experience -------------------------------------------------------------------------------- /stack/index.js: -------------------------------------------------------------------------------- 1 | class Stack { 2 | constructor() { 3 | this.items = []; // Initialize an empty array 4 | } 5 | 6 | // Add an item to the stack 7 | push(element) { 8 | this.items.push(element); 9 | } 10 | 11 | // Remove and return the top item 12 | pop() { 13 | if (this.isEmpty()) { 14 | return "Stack is empty!"; 15 | } 16 | return this.items.pop(); 17 | } 18 | 19 | // Check if the stack is empty 20 | isEmpty() { 21 | return this.items.length === 0; 22 | } 23 | 24 | // Peek at the top item without removing it 25 | peek() { 26 | if (this.isEmpty()) { 27 | return "Stack is empty!"; 28 | } 29 | return this.items[this.items.length - 1]; 30 | } 31 | 32 | // Get the size of the stack 33 | size() { 34 | return this.items.length; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /stack/task.js: -------------------------------------------------------------------------------- 1 | class Stack { 2 | constructor() { 3 | this.items = []; 4 | } 5 | 6 | push(element) { 7 | this.items.push(element); 8 | } 9 | 10 | pop() { 11 | if (this.isEmpty()) { 12 | return null; 13 | } 14 | return this.items.pop(); 15 | } 16 | 17 | peek() { 18 | if (this.isEmpty()) { 19 | return null; 20 | } 21 | return this.items[this.items.length - 1]; 22 | } 23 | 24 | isEmpty() { 25 | return this.items.length === 0; 26 | } 27 | } 28 | 29 | function isBalanced(expression) { 30 | const stack = new Stack(); 31 | const openingBrackets = "({["; 32 | const closingBrackets = ")}]"; 33 | const matchingBrackets = { 34 | ")": "(", 35 | "}": "{", 36 | "]": "[", 37 | }; 38 | 39 | for (const char of expression) { 40 | if (openingBrackets.includes(char)) { 41 | stack.push(char); 42 | } else if (closingBrackets.includes(char)) { 43 | if (stack.isEmpty() || stack.pop() !== matchingBrackets[char]) { 44 | return false; 45 | } 46 | } 47 | } 48 | 49 | return stack.isEmpty(); 50 | } 51 | 52 | // Test cases 53 | console.log(isBalanced("(a + b) * (c - d)")); // Output: true 54 | console.log(isBalanced("{[()]}")); // Output: true 55 | console.log(isBalanced("{[(])}")); // Output: false 56 | console.log(isBalanced("((a + b)")); // Output: false 57 | -------------------------------------------------------------------------------- /stack/task.md: -------------------------------------------------------------------------------- 1 | ### Task 1: Balanced Parentheses 2 | **Problem:** 3 | Given a string containing just the characters `'('`, `')'`, `{`, `'}'`, `[` and `]`, determine if the input string is valid. An input string is valid if: 4 | - Open brackets must be closed by the corresponding closing bracket. 5 | - Open brackets must be closed in the correct order. 6 | 7 | **Input:** 8 | - String: `"{[()()]}"` 9 | 10 | **Output:** 11 | - Result: `true` 12 | 13 | --- 14 | 15 | ### Task 2: Reverse a String 16 | **Problem:** 17 | Write a function that reverses a string using a stack data structure. 18 | 19 | **Input:** 20 | - String: `"hello"` 21 | 22 | **Output:** 23 | - Reversed string: `"olleh"` 24 | 25 | --- 26 | 27 | ### Task 3: Evaluate Reverse Polish Notation (RPN) 28 | **Problem:** 29 | Evaluate the value of an arithmetic expression in Reverse Polish Notation (RPN). Valid operators are `+`, `-`, `*`, and `/`. Each operand may be an integer or another expression. 30 | 31 | **Input:** 32 | - RPN expression: `["2", "1", "+", "3", "*"]` 33 | 34 | **Output:** 35 | - Result: `9` 36 | 37 | --- 38 | 39 | ### Task 4: Min Stack 40 | **Problem:** 41 | Design a stack that supports the following operations: 42 | - `push(x)` — Push the element `x` onto the stack. 43 | - `pop()` — Removes the element on the top of the stack. 44 | - `top()` — Get the top element. 45 | - `getMin()` — Retrieve the minimum element in the stack. 46 | 47 | **Input:** 48 | - Operations: 49 | 1. `push(5)` 50 | 2. `push(3)` 51 | 3. `getMin()` 52 | 4. `pop()` 53 | 5. `getMin()` 54 | 55 | **Output:** 56 | - Result: 57 | 1. `null` (for `push` operations) 58 | 2. `3` (for `getMin()`) 59 | 3. `null` (for `pop()`) 60 | 4. `5` (for `getMin()`) 61 | 62 | --- 63 | 64 | ### Task 5: Next Greater Element 65 | **Problem:** 66 | Given an array of integers, find the next greater element for each element in the array. The next greater element for an element `x` is the first greater element that is to the right of `x` in the array. If no such element exists, output `-1`. 67 | 68 | **Input:** 69 | - Array: `[4, 5, 2, 10, 8]` 70 | 71 | **Output:** 72 | - Result: `[5, 10, 10, -1, -1]` 73 | 74 | --- 75 | -------------------------------------------------------------------------------- /trie/README.md: -------------------------------------------------------------------------------- 1 | # Trie (Prefix Tree) Data Structure in JavaScript 🚀 2 | 3 | ## 0-5 minutes: Check the Home Task 4 | - Review solutions. 5 | - Discuss any issues and common mistakes encountered. 6 | - Clarify doubts related to the home task. 7 | 8 | ### Key Points to Address: 9 | - If any of the students faced issues with basic concepts like **arrays**, **linked lists**, or **stacks**, address those foundational concepts briefly before moving forward. 10 | - Explain the **Trie (Prefix Tree)** data structure to everyone: 11 | - A **Trie (Prefix Tree)** is a tree-like data structure used to store strings, where each node represents a character in the string. 12 | - It is mainly used for **prefix matching** and is efficient for tasks like autocomplete and dictionary lookups. 13 | - The key operations are: 14 | - **insert(word)**: Adds a word to the trie. 15 | - **search(word)**: Checks if a word exists in the trie. 16 | - **startsWith(prefix)**: Checks if there is any word in the trie that starts with the given prefix. 17 | 18 | ## 5-10 minutes: Introduction to Trie and its Key Operations 19 | - Explain the **Trie (Prefix Tree)** data structure and its real-world analogy (like a phonebook or dictionary). 20 | - Discuss key operations: 21 | - **insert(word)**: Adds a word to the trie. 22 | - **search(word)**: Checks if a word exists in the trie. 23 | - **startsWith(prefix)**: Checks if there is any word in the trie that starts with the given prefix. 24 | 25 | ## 10-20 minutes: Implement a Trie Class from Scratch 26 | - Guide students to implement a Trie class in JavaScript. 27 | - The class should support the following methods: 28 | - `insert(word)` 29 | - `search(word)` 30 | - `startsWith(prefix)` 31 | 32 | Example: 33 | 34 | ```javascript 35 | class TrieNode { 36 | constructor() { 37 | this.children = {}; 38 | this.isEndOfWord = false; 39 | } 40 | } 41 | 42 | class Trie { 43 | constructor() { 44 | this.root = new TrieNode(); 45 | } 46 | 47 | // Adds a word to the trie 48 | insert(word) { 49 | let node = this.root; 50 | for (let char of word) { 51 | if (!node.children[char]) { 52 | node.children[char] = new TrieNode(); 53 | } 54 | node = node.children[char]; 55 | } 56 | node.isEndOfWord = true; 57 | } 58 | 59 | // Checks if a word exists in the trie 60 | search(word) { 61 | let node = this.root; 62 | for (let char of word) { 63 | if (!node.children[char]) { 64 | return false; 65 | } 66 | node = node.children[char]; 67 | } 68 | return node.isEndOfWord; 69 | } 70 | 71 | // Checks if there is any word that starts with the given prefix 72 | startsWith(prefix) { 73 | let node = this.root; 74 | for (let char of prefix) { 75 | if (!node.children[char]) { 76 | return false; 77 | } 78 | node = node.children[char]; 79 | } 80 | return true; 81 | } 82 | } 83 | 84 | // Create a new Trie 85 | const trie = new Trie(); 86 | 87 | // Insert words into the Trie 88 | trie.insert("apple"); 89 | trie.insert("app"); 90 | trie.insert("bat"); 91 | trie.insert("ball"); 92 | 93 | // Search for words 94 | console.log(trie.search("apple")); // true (word exists) 95 | console.log(trie.search("app")); // true (word exists) 96 | console.log(trie.search("bat")); // true (word exists) 97 | console.log(trie.search("bake")); // false (word doesn't exist) 98 | 99 | // Check for prefixes 100 | console.log(trie.startsWith("app")); // true (there are words starting with "app") 101 | console.log(trie.startsWith("ba")); // true (there are words starting with "ba") 102 | console.log(trie.startsWith("cat")); // false (no words start with "cat") 103 | ``` 104 | 105 | ## 20-30 minutes: Task - Implement a Trie-based Solution for a Problem 106 | - Assign a task where students need to solve a problem using the Trie. 107 | - Example problem: Implement a search function that checks if any word in the trie starts with a given prefix. 108 | 109 | ## 30-40 minutes: Home Task - Solve a Problem Using Trie from LeetCode 110 | - Provide a LeetCode problem that can be solved using the Trie data structure. 111 | - Students can work on this problem during the session or as homework. 112 | 113 | --- 114 | 115 | ## Connect with Me: 116 | - [LinkedIn - Vitalii Semianchuk](https://www.linkedin.com/in/vitalii-semianchuk-9812a786/) 117 | - [Telegram - @jsmentorfree](https://t.me/jsmentorfree) - We do a lot of free teaching on this channel! Join us to learn and grow in web development. 118 | - [Tiktok - @jsmentoring](https://www.tiktok.com/@jsmentoring) Everyday new videos 119 | - [Youtube - @jsmentor-uk](https://www.youtube.com/@jsmentor-uk) Mentor live streams 120 | - [Dev.to - fix2015](https://dev.to/fix2015) Javascript featured, live, experience 121 | -------------------------------------------------------------------------------- /trie/index.js: -------------------------------------------------------------------------------- 1 | class TrieNode { 2 | constructor() { 3 | this.children = {}; 4 | this.isEndOfWord = false; 5 | } 6 | } 7 | 8 | class Trie { 9 | constructor() { 10 | this.root = new TrieNode(); 11 | } 12 | 13 | // Insert a word into the trie 14 | insert(word) { 15 | let currentNode = this.root; 16 | for (let char of word) { 17 | if (!currentNode.children[char]) { 18 | currentNode.children[char] = new TrieNode(); 19 | } 20 | currentNode = currentNode.children[char]; 21 | } 22 | currentNode.isEndOfWord = true; 23 | } 24 | 25 | // Search for a word in the trie 26 | search(word) { 27 | let currentNode = this.root; 28 | for (let char of word) { 29 | if (!currentNode.children[char]) { 30 | return false; 31 | } 32 | currentNode = currentNode.children[char]; 33 | } 34 | return currentNode.isEndOfWord; 35 | } 36 | 37 | // Check if any word in the trie starts with the given prefix 38 | startsWith(prefix) { 39 | let currentNode = this.root; 40 | for (let char of prefix) { 41 | if (!currentNode.children[char]) { 42 | return false; 43 | } 44 | currentNode = currentNode.children[char]; 45 | } 46 | return true; 47 | } 48 | 49 | // Delete a word from the trie 50 | delete(word) { 51 | this.deleteHelper(this.root, word, 0); 52 | } 53 | 54 | // Helper function to delete a word 55 | deleteHelper(node, word, index) { 56 | if (index === word.length) { 57 | if (!node.isEndOfWord) return false; 58 | node.isEndOfWord = false; 59 | return Object.keys(node.children).length === 0; 60 | } 61 | 62 | const char = word[index]; 63 | if (!node.children[char]) return false; 64 | 65 | const shouldDeleteCurrentNode = this.deleteHelper(node.children[char], word, index + 1); 66 | 67 | if (shouldDeleteCurrentNode) { 68 | delete node.children[char]; 69 | return Object.keys(node.children).length === 0; 70 | } 71 | 72 | return false; 73 | } 74 | } 75 | 76 | // Initialize the trie 77 | const trie = new Trie(); 78 | 79 | // Insert words into the trie 80 | trie.insert("apple"); 81 | trie.insert("app"); 82 | 83 | // Search for words 84 | console.log(trie.search("apple")); // Output: true 85 | console.log(trie.search("app")); // Output: true 86 | console.log(trie.search("appl")); // Output: false 87 | 88 | // Check if any word starts with a given prefix 89 | console.log(trie.startsWith("app")); // Output: true 90 | console.log(trie.startsWith("appl")); // Output: true 91 | console.log(trie.startsWith("banana")); // Output: false 92 | 93 | // Delete a word from the trie 94 | trie.delete("app"); 95 | console.log(trie.search("app")); // Output: false 96 | console.log(trie.search("apple")); // Output: true 97 | -------------------------------------------------------------------------------- /trie/task.md: -------------------------------------------------------------------------------- 1 | ### Task 1: Autocomplete System 2 | **Problem:** 3 | Design an autocomplete system for a search engine or messaging app that suggests possible completions based on the user’s input. The system should be able to return a list of suggestions quickly as the user types. 4 | 5 | **Input:** 6 | - A list of words: `["apple", "appetizer", "application", "banana", "band", "bandit"]` 7 | - User input: `"app"` 8 | 9 | **Output:** 10 | - List of suggestions: `["apple", "appetizer", "application"]` 11 | 12 | --- 13 | 14 | ### Task 2: Word Search 15 | **Problem:** 16 | Given a 2D board of characters and a list of words, return all the words from the list that can be formed by a sequence of adjacent characters in the grid (horizontally or vertically). 17 | 18 | **Input:** 19 | - Board: 20 | ```[ 21 | ['o', 'a', 'a', 'n'], 22 | ['e', 't', 'a', 'e'], 23 | ['i', 'h', 'k', 'r'], 24 | ['i', 'f', 'l', 'v'] 25 | ]``` 26 | - List of words: `["oath", "pea", "eat", "rain"]` 27 | 28 | **Output:** 29 | - List of found words: `["oath", "eat"]` 30 | 31 | --- 32 | 33 | ### Task 3: Implement a Dictionary for Spell Checking 34 | **Problem:** 35 | Implement a spell checker that uses a dictionary to identify and correct spelling errors. Given a list of words, suggest possible corrections for a misspelled word by checking the closest matches in the dictionary. 36 | 37 | **Input:** 38 | - Dictionary: `["hello", "hell", "world", "help"]` 39 | - Misspelled word: `"helo"` 40 | 41 | **Output:** 42 | - Suggested corrections: `["hello", "hell"]` 43 | 44 | --- 45 | 46 | ### Task 4: Longest Prefix Match 47 | **Problem:** 48 | Given a list of words, find the longest common prefix among all of them. 49 | 50 | **Input:** 51 | - List of words: `["flower", "flow", "flight"]` 52 | 53 | **Output:** 54 | - Longest common prefix: `"fl"` 55 | 56 | --- 57 | --------------------------------------------------------------------------------