├── 1. Introduction └── 1. The Problem.js ├── 2. Big O ├── 1. Linear Time.js ├── 2. Constant Time.js └── 3. Quadratic Time.js ├── 3. Arrays ├── 1. Intro │ └── index.js ├── 2. Custom Array │ └── index.js └── 3. Challenges │ ├── 1. Reverse String.js │ ├── 2. Palindromes.js │ ├── 3. Integer Reversal.js │ ├── 4. Sentence Capitalization.js │ ├── 5. FizzBuzz.js │ ├── 6. MaxProfit.js │ ├── 7. Array Chunk.js │ └── 8. Two Sum.js ├── 4. LinkedList ├── 1. Singly LinkedList │ └── index.js ├── 2. Doubly LinkedList │ └── index.js └── 3. Challenges │ └── 1. Reverse LinkedList.js ├── 5. Stack & Queue ├── 1. Stack │ └── index.js ├── 2. Queue │ └── index.js └── 3. Challenges │ ├── 1. Min Stack.js │ ├── 2. Valid Parenthesis.js │ └── 3. Reverse String Using Stack.js ├── 6. Hash Table ├── 1. Custom Hash Table │ └── index.js └── 2. Challenges │ ├── 1. Word Instance Counter │ └── index.js │ ├── 2. Two Sum │ └── index.js │ └── 3. Group Anagrams │ └── index.js ├── 7. Tree ├── 1. BST │ └── index.js ├── 2. Recursion │ └── index.js └── 3. Tree Traversal │ └── index.js ├── 8. Graphs └── index.js ├── 9. Sorting Algo ├── 1. Bubble Sort │ └── index.js ├── 2. Selection Sort │ └── index.js ├── 3. Insertion Sort │ └── index.js └── 4. Merge Sort │ └── index.js ├── README.md └── thumb.png /1. Introduction/1. The Problem.js: -------------------------------------------------------------------------------- 1 | // Data Structure 👇 2 | const studentsDatabase = ["jordan", "erick", "john", "michel"]; 3 | 4 | // Algorithm for finding a specific user 5 | const findStudent = (allStudents, studentName) => { 6 | for (let i = 0; i < allStudents.length; i++) { 7 | if (allStudents[i] === studentName) { 8 | console.log(`Found ${studentName}`); 9 | } 10 | } 11 | }; 12 | 13 | findStudent(studentsDatabase, "erick"); 14 | -------------------------------------------------------------------------------- /2. Big O/1. Linear Time.js: -------------------------------------------------------------------------------- 1 | // ----------------------------------- 2 | // const groceries = ["milk", "bread", "eggs", "flour", "cheese", "sugar"]; 3 | 4 | // const searchForItem = (item) => { 5 | // for (let i = 0; i < groceries.length; i++) { 6 | // if (groceries[i] === item) { 7 | // console.log(`Found ${item}`); 8 | // } 9 | // } 10 | // }; 11 | 12 | // searchForItem("eggs"); 13 | // ----------------------------------- 14 | 15 | const groceries = ["milk", "bread", "eggs", "flour", "cheese", "sugar"]; 16 | 17 | const searchForItem = (item) => { 18 | for (let i = 0; i < groceries.length; i++) { 19 | if (groceries[i] === item) { 20 | console.log(`Found ${item}`); 21 | } 22 | } 23 | 24 | for (let j = 0; j < groceries.length; j++) { 25 | if (groceries[j] === item) { 26 | console.log(`Found ${item} 2`); 27 | } 28 | } 29 | 30 | // n + n = 2n -> O(2n) 31 | // Drop the constant so it becomes O(n) 32 | }; 33 | 34 | searchForItem("eggs"); 35 | -------------------------------------------------------------------------------- /2. Big O/2. Constant Time.js: -------------------------------------------------------------------------------- 1 | const numbers = [1, 2, 3, 4, 5]; 2 | const getElement = (arr, index) => arr[index]; 3 | console.log(getElement(numbers, 0)); 4 | -------------------------------------------------------------------------------- /2. Big O/3. Quadratic Time.js: -------------------------------------------------------------------------------- 1 | // ------------------------------------ 2 | // function findPairs(arr) { 3 | // for (let i = 0; i < arr.length; i++) { 4 | // for (let j = i + 1; j < arr.length; j++) { 5 | // console.log(`Pair: ${arr[i]}, ${arr[j]}`); 6 | // } 7 | // } 8 | // } 9 | 10 | // const numbers = [1, 2, 3, 4, 5]; 11 | // findPairs(numbers); 12 | // ------------------------------------ 13 | 14 | // ------------------------------------ 15 | // Drop Non-Dominants 16 | function findPairs(arr) { 17 | // O(n^2) 18 | for (let i = 0; i < arr.length; i++) { 19 | for (let j = i + 1; j < arr.length; j++) { 20 | console.log(`Pair: ${arr[i]}, ${arr[j]}`); 21 | } 22 | } 23 | 24 | // O(n) 25 | for (let q = 0; q < 5; q++) { 26 | console.log("-------------", q); 27 | } 28 | 29 | // If we combine all the "O" operations it becomes O(n^2 + n) 30 | // O(n^2) is a Dominant term 31 | // "n" is a Non-Dominant term 32 | // So we remove the "non-dominant" term and we're only left with O(n^2) 33 | // This way, we simplify our bigO 34 | } 35 | 36 | const numbers = [1, 2, 3, 4, 5]; 37 | findPairs(numbers); 38 | // ------------------------------------ 39 | -------------------------------------------------------------------------------- /3. Arrays/1. Intro/index.js: -------------------------------------------------------------------------------- 1 | const stringArr = ["a", "b", "c", "d"]; 2 | const numArr = [1, 2, 3, 4, 5]; 3 | const boolArr = [true, false]; 4 | const mixed = ["a", 2, true, undefined, null, { a: "a" }, ["b"]]; 5 | console.log(mixed); 6 | -------------------------------------------------------------------------------- /3. Arrays/2. Custom Array/index.js: -------------------------------------------------------------------------------- 1 | class MyArray { 2 | constructor() { 3 | this.length = 0; 4 | this.data = {}; 5 | } 6 | 7 | push(item) { 8 | this.data[this.length] = item; 9 | this.length++; 10 | return this.length; 11 | } 12 | 13 | get(index) { 14 | return this.data[index]; 15 | } 16 | 17 | pop() { 18 | const lastItem = this.data[this.length - 1]; 19 | delete this.data[this.length - 1]; 20 | this.length--; 21 | return lastItem; 22 | } 23 | 24 | shift() { 25 | const firstItem = this.data[0]; 26 | 27 | for (let i = 0; i < this.length; i++) { 28 | this.data[i] = this.data[i + 1]; 29 | } 30 | 31 | // Delete the last element (which now contains the original second element) 32 | delete this.data[this.length - 1]; 33 | this.length--; 34 | 35 | // Return the first item that was removed from the array 36 | return firstItem; 37 | } 38 | 39 | delete(index) { 40 | // Store the item to be removed 41 | const item = this.data[index]; 42 | 43 | // Shift elements after the target element (excluding the last one) 44 | for (let i = index; i < this.length - 1; i++) { 45 | this.data[i] = this.data[i + 1]; 46 | } 47 | 48 | // Delete the last element (which now holds the element to be removed) 49 | delete this.data[this.length - 1]; 50 | 51 | // Decrement length 52 | this.length--; 53 | 54 | // Return the removed item 55 | return item; 56 | } 57 | } 58 | 59 | const myNewArray = new MyArray(); 60 | myNewArray.push("one"); 61 | myNewArray.push("two"); 62 | myNewArray.push("three"); 63 | // myNewArray.pop(); 64 | // myNewArray.shift(); 65 | myNewArray.delete(1); 66 | // console.log(myNewArray.get(0)); 67 | console.log(myNewArray); 68 | -------------------------------------------------------------------------------- /3. Arrays/3. Challenges/1. Reverse String.js: -------------------------------------------------------------------------------- 1 | // 1. Convert string to array (split method) 2 | // 2. Reverse the array (reverse method) 3 | // 3. Convert array back to string (join method) 4 | 5 | const reverseString = (str) => str.split("").reverse().join(""); 6 | console.log(reverseString("hello")); 7 | -------------------------------------------------------------------------------- /3. Arrays/3. Challenges/2. Palindromes.js: -------------------------------------------------------------------------------- 1 | // 1. Convert string to array (split method) 2 | // 2. Reverse the array (reverse method) 3 | // 3. Convert array back to string (join method) 4 | // 4. Compare strings 5 | 6 | const palindrome = (str) => str.split("").reverse().join("") === str; 7 | 8 | console.log(palindrome("cddc")); 9 | console.log(palindrome("Hello")); 10 | -------------------------------------------------------------------------------- /3. Arrays/3. Challenges/3. Integer Reversal.js: -------------------------------------------------------------------------------- 1 | // 1. Convert number to string (toString method) 2 | // 2. Convert String to array (split method) 3 | // 3. Reverse the string (reverse method) 4 | // 4. Convert array back to string (join method) 5 | // 5. Convert string to number (parseInt method) 6 | // 6. Return the number 7 | 8 | const reverseInt = (n) => { 9 | const reversed = n.toString().split("").reverse().join(""); 10 | return parseInt(reversed) * Math.sign(n); 11 | }; 12 | 13 | console.log(reverseInt(-123)); 14 | -------------------------------------------------------------------------------- /3. Arrays/3. Challenges/4. Sentence Capitalization.js: -------------------------------------------------------------------------------- 1 | // 1. Make the string lowercase (toLowerCase method) 2 | // 2. Convert string to array (split method) 3 | // 3. Capitalize each word (map method) 4 | // 3. Convert array back to string (join method) 5 | 6 | const capitalize = (str) => { 7 | return str 8 | .toLowerCase() 9 | .split(" ") 10 | .map((word) => word[0].toUpperCase() + word.slice(1)) 11 | .join(" "); 12 | }; 13 | 14 | console.log(capitalize("hello world")); 15 | console.log(capitalize("jordan peterson")); 16 | -------------------------------------------------------------------------------- /3. Arrays/3. Challenges/5. FizzBuzz.js: -------------------------------------------------------------------------------- 1 | // 1. Print numbers from 1 to n 2 | // 2. If number is divisible by 3, print "Fizz" 3 | // 3. If number is divisible by 5, print "Buzz" 4 | // 4. If number is divisible by 3 and 5, print "FizzBuzz" 5 | // 5. Else, print the number 6 | 7 | const fizzBuzz = (n) => { 8 | for (let i = 1; i <= n; i++) { 9 | if (i % 3 === 0 && i % 5 === 0) { 10 | console.log("FizzBuzz"); 11 | } else if (i % 3 === 0) { 12 | console.log("Fizz"); 13 | } else if (i % 5 === 0) { 14 | console.log("Buzz"); 15 | } else { 16 | console.log(i); 17 | } 18 | } 19 | }; 20 | 21 | fizzBuzz(15); 22 | -------------------------------------------------------------------------------- /3. Arrays/3. Challenges/6. MaxProfit.js: -------------------------------------------------------------------------------- 1 | const maxProfit = (prices) => { 2 | let minPrice = prices[0]; // Assume the first day is the cheapest to buy 3 | let maxProfit = 0; 4 | 5 | for (let i = 1; i < prices.length; i++) { 6 | const currentPrice = prices[i]; 7 | // console.log(currentPrice); 8 | 9 | // Update minimum price if a lower price is found 10 | minPrice = Math.min(minPrice, currentPrice); 11 | // console.log(minPrice); 12 | 13 | // Calculate potential profit for selling today 14 | const potentialProfit = currentPrice - minPrice; 15 | // console.log(potentialProfit); 16 | 17 | // Update maxProfit if a higher profit is found 18 | maxProfit = Math.max(maxProfit, potentialProfit); 19 | // console.log(maxProfit); 20 | } 21 | 22 | return maxProfit; 23 | }; 24 | 25 | const prices = [7, 1, 5, 3, 6, 4]; 26 | const profit = maxProfit(prices); 27 | console.log("Maximum profit:", profit); 28 | -------------------------------------------------------------------------------- /3. Arrays/3. Challenges/7. Array Chunk.js: -------------------------------------------------------------------------------- 1 | const chunk = (array, size) => { 2 | const chunked = []; 3 | let index = 0; 4 | 5 | while (index < array.length) { 6 | const chunk = array.slice(index, index + size); 7 | // console.log("------------", chunk); 8 | chunked.push(chunk); 9 | index += size; 10 | } 11 | 12 | return chunked; 13 | }; 14 | 15 | // console.log(chunk([1, 2, 3, 4, 5], 2)); 16 | console.log(chunk([1, 2, 3, 4, 5, 6, 7, 8], 3)); 17 | -------------------------------------------------------------------------------- /3. Arrays/3. Challenges/8. Two Sum.js: -------------------------------------------------------------------------------- 1 | // ⚠️ This is not better solution, we'll make it better in the upcoming videos! 2 | 3 | function twoSum(nums, target) { 4 | // Loop through each number in the list 5 | for (let i = 0; i < nums.length; i++) { 6 | // For each number, check the rest of the list 7 | for (let j = i + 1; j < nums.length; j++) { 8 | // If the current number and the one we're checking add up to the target, return their indexes 9 | if (nums[i] + nums[j] === target) { 10 | return [i, j]; 11 | } 12 | } 13 | } 14 | 15 | // If no matching pair is found, return an empty array 16 | return []; 17 | } 18 | 19 | const res = twoSum([2, 7, 11, 15], 9); 20 | const res2 = twoSum([1, 3, 7, 9, 2], 11); 21 | console.log(res); 22 | console.log(res2); 23 | -------------------------------------------------------------------------------- /4. LinkedList/1. Singly LinkedList/index.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(value) { 3 | this.head = value; 4 | this.next = null; 5 | } 6 | } 7 | 8 | class LinkedList { 9 | constructor(value) { 10 | this.head = new Node(value); 11 | this.tail = this.head; 12 | this.length = 1; 13 | } 14 | 15 | push(value) { 16 | let newNode = new Node(value); 17 | 18 | if (!this.head) { 19 | this.head = newNode; 20 | this.tail = newNode; 21 | } 22 | 23 | this.tail.next = newNode; 24 | this.tail = newNode; 25 | this.length++; 26 | } 27 | 28 | pop() { 29 | if (!this.head) { 30 | return undefined; 31 | } 32 | 33 | let temp = this.head; 34 | let prev = this.head; 35 | 36 | while (temp.next) { 37 | // console.log("********** temp", temp); 38 | prev = temp; 39 | temp = prev.next; 40 | } 41 | 42 | // console.log(prev); 43 | this.tail = prev; 44 | this.tail.next = null; 45 | this.length--; 46 | 47 | if (this.length === 0) { 48 | this.head = null; 49 | this.tail = null; 50 | } 51 | 52 | return temp; 53 | } 54 | 55 | unshift(value) { 56 | const newNode = new Node(value); 57 | 58 | if (!this.head) { 59 | this.head = newNode; 60 | this.tail = newNode; 61 | } 62 | 63 | newNode.next = this.head; 64 | this.head = newNode; 65 | this.length++; 66 | return this; 67 | } 68 | 69 | shift() { 70 | if (!this.head) { 71 | return undefined; 72 | } 73 | 74 | // 1. Point to the first node/element 75 | let temp = this.head; 76 | // 2. Move the head to the next node/element 77 | this.head = this.head.next; 78 | // 3. Remove first element 79 | temp.next = null; 80 | this.length--; 81 | 82 | // If we have one node in the list 83 | if (this.length === 0) { 84 | this.tail = null; 85 | } 86 | 87 | return temp; 88 | } 89 | 90 | getFirst() { 91 | return this.head; 92 | } 93 | 94 | getLast() { 95 | if (!this.head) { 96 | return null; 97 | } 98 | 99 | let node = this.head; 100 | 101 | while (node) { 102 | // console.log("***********", node); 103 | if (!node.next) { 104 | return node; 105 | } 106 | node = node.next; 107 | } 108 | } 109 | 110 | get(index) { 111 | let counter = 0; 112 | let node = this.head; 113 | 114 | while (node) { 115 | if (counter === index) { 116 | return node; 117 | } 118 | 119 | counter++; 120 | node = node.next; 121 | } 122 | 123 | return null; 124 | } 125 | 126 | set(index, value) { 127 | let temp = this.get(index); 128 | console.log("----------", temp); 129 | 130 | if (temp) { 131 | temp.value = value; 132 | return true; 133 | } 134 | 135 | return false; 136 | } 137 | 138 | insert(index, value) { 139 | if (index === 0) { 140 | return this.unshift(value); 141 | } 142 | 143 | if (index === this.length) { 144 | return this.push(value); 145 | } 146 | 147 | const newNode = new Node(value); 148 | // Uses the get method to find the node right before the desired position (index - 1). 149 | const temp = this.get(index - 1); 150 | 151 | newNode.next = temp.next; 152 | temp.next = newNode; 153 | this.length++; 154 | return true; 155 | } 156 | 157 | size() { 158 | let counter = 0; 159 | let node = this.head; 160 | 161 | while (node) { 162 | counter++; 163 | node = node.next; 164 | } 165 | 166 | return counter; 167 | } 168 | 169 | clear() { 170 | this.head = null; 171 | } 172 | } 173 | 174 | const myLinkedList = new LinkedList(1); 175 | myLinkedList.push(2); 176 | myLinkedList.push(3); 177 | console.log(myLinkedList); 178 | -------------------------------------------------------------------------------- /4. LinkedList/2. Doubly LinkedList/index.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(value) { 3 | this.value = value; 4 | this.next = null; 5 | this.prev = null; 6 | } 7 | } 8 | 9 | class DoublyLinkedList { 10 | constructor(value) { 11 | const newNode = new Node(value); 12 | this.head = newNode; 13 | this.tail = this.head; 14 | this.length = 1; 15 | } 16 | 17 | push(value) { 18 | const newNode = new Node(value); 19 | 20 | if (!this.head) { 21 | this.head = newNode; 22 | this.tail = newNode; 23 | } else { 24 | this.tail.next = newNode; 25 | newNode.prev = this.tail; 26 | this.tail = newNode; 27 | } 28 | 29 | this.length++; 30 | return this; 31 | } 32 | 33 | pop() { 34 | if (this.length === 0) { 35 | return undefined; 36 | } 37 | 38 | let temp = this.tail; 39 | 40 | if (this.length === 1) { 41 | this.head = null; 42 | this.tail = null; 43 | } else { 44 | this.tail = this.tail.prev; 45 | this.tail.next = null; 46 | temp.prev = null; 47 | } 48 | 49 | this.length--; 50 | return temp; 51 | } 52 | 53 | unshift(value) { 54 | const newNode = new Node(value); 55 | 56 | if (this.length === 0) { 57 | this.head = newNode; 58 | this.tail = newNode; 59 | } else { 60 | newNode.next = this.head; 61 | this.head.prev = newNode; 62 | this.head = newNode; 63 | } 64 | 65 | this.length++; 66 | return this; 67 | } 68 | 69 | shift() { 70 | if (this.length === 0) { 71 | return undefined; 72 | } 73 | 74 | let temp = this.head; 75 | 76 | if (this.length === 1) { 77 | this.head = null; 78 | this.tail = null; 79 | } else { 80 | this.head = this.head.next; 81 | this.head.prev = null; 82 | temp.next = null; 83 | } 84 | this.length--; 85 | return temp; 86 | } 87 | } 88 | 89 | let myDoublyLinkedList = new DoublyLinkedList(0); 90 | myDoublyLinkedList.push(1); 91 | // myDoublyLinkedList.pop(); 92 | // myDoublyLinkedList.shift(); 93 | console.log(myDoublyLinkedList); 94 | -------------------------------------------------------------------------------- /4. LinkedList/3. Challenges/1. Reverse LinkedList.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(value) { 3 | this.head = value; 4 | this.next = null; 5 | } 6 | } 7 | 8 | class LinkedList { 9 | constructor(value) { 10 | this.head = new Node(value); 11 | this.tail = this.head; 12 | this.length = 1; 13 | } 14 | 15 | push(value) { 16 | let newNode = new Node(value); 17 | 18 | if (!this.head) { 19 | this.head = newNode; 20 | this.tail = newNode; 21 | } 22 | 23 | this.tail.next = newNode; 24 | this.tail = newNode; 25 | this.length++; 26 | } 27 | 28 | reverse() { 29 | let temp = this.head; 30 | this.head = this.tail; 31 | this.tail = temp; 32 | let next = temp; 33 | let prev = null; 34 | 35 | for (let i = 0; i < this.length; i++) { 36 | next = temp.next; 37 | temp.next = prev; 38 | prev = temp; 39 | temp = next; 40 | } 41 | 42 | return this; 43 | } 44 | } 45 | 46 | const myLinkedList = new LinkedList(1); 47 | myLinkedList.push(2); 48 | myLinkedList.push(3); 49 | myLinkedList.push(4); 50 | console.log(myLinkedList.reverse()); 51 | -------------------------------------------------------------------------------- /5. Stack & Queue/1. Stack/index.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(value) { 3 | this.value = value; 4 | this.next = null; 5 | } 6 | } 7 | 8 | class Stack { 9 | constructor(value) { 10 | const newNode = new Node(value); 11 | this.first = newNode; 12 | this.length = 1; 13 | } 14 | 15 | push(value) { 16 | const newNode = new Node(value); 17 | 18 | if (this.length === 0) { 19 | this.first = newNode; 20 | } else { 21 | newNode.next = this.first; 22 | this.first = newNode; 23 | this.length++; 24 | return this; 25 | } 26 | } 27 | 28 | pop() { 29 | if (this.length === 0) { 30 | return undefined; 31 | } 32 | 33 | let temp = this.first; 34 | this.first = this.first.next; 35 | temp.next = null; 36 | this.length--; 37 | return temp; 38 | } 39 | 40 | top() { 41 | if (this.length === 0) { 42 | return undefined; 43 | } 44 | return this.first; 45 | } 46 | } 47 | 48 | let theStack = new Stack(0); 49 | theStack.push(1); 50 | theStack.push(2); 51 | // theStack.pop(); 52 | console.log(theStack); 53 | -------------------------------------------------------------------------------- /5. Stack & Queue/2. Queue/index.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(value) { 3 | this.value = value; 4 | this.next = null; 5 | } 6 | } 7 | 8 | class Queue { 9 | constructor(value) { 10 | const newNode = new Node(value); 11 | this.first = newNode; 12 | this.last = newNode; 13 | this.length = 1; 14 | } 15 | 16 | enqueue(value) { 17 | const newNode = new Node(value); 18 | if (this.length === 0) { 19 | this.first = newNode; 20 | this.last = newNode; 21 | } 22 | 23 | this.last.next = newNode; 24 | this.last = newNode; 25 | this.length++; 26 | return this; 27 | } 28 | 29 | dequeue() { 30 | if (this.length === 0) { 31 | return undefined; 32 | } 33 | 34 | let temp = this.first; 35 | 36 | if (this.length === 1) { 37 | this.first = null; 38 | this.last = null; 39 | } 40 | 41 | this.first = this.first.next; 42 | temp.next = null; 43 | this.length--; 44 | return temp; 45 | } 46 | } 47 | 48 | let myQueue = new Queue(0); 49 | myQueue.enqueue(1); 50 | myQueue.enqueue(2); 51 | myQueue.dequeue(); 52 | console.log(myQueue); 53 | -------------------------------------------------------------------------------- /5. Stack & Queue/3. Challenges/1. Min Stack.js: -------------------------------------------------------------------------------- 1 | class Node { 2 | constructor(value) { 3 | this.value = value; 4 | this.next = null; 5 | } 6 | } 7 | 8 | class Stack { 9 | constructor(value) { 10 | const newNode = new Node(value); 11 | this.first = newNode; 12 | this.length = 1; 13 | } 14 | 15 | push(value) { 16 | const newNode = new Node(value); 17 | 18 | if (this.length === 0) { 19 | this.first = newNode; 20 | } else { 21 | newNode.next = this.first; 22 | this.first = newNode; 23 | this.length++; 24 | } 25 | return this; 26 | } 27 | 28 | pop() { 29 | if (this.length === 0) { 30 | return undefined; 31 | } 32 | 33 | let temp = this.first; 34 | this.first = this.first.next; 35 | temp.next = null; 36 | this.length--; 37 | return temp; 38 | } 39 | 40 | top() { 41 | if (this.length === 0) { 42 | return undefined; 43 | } 44 | return this.first; 45 | } 46 | 47 | min() { 48 | if (this.length === 0) { 49 | return undefined; 50 | } 51 | 52 | let current = this.first; 53 | let minValue = current.value; 54 | 55 | while (current.next) { 56 | current = current.next; 57 | if (current.value < minValue) { 58 | console.log(current.value, minValue); 59 | minValue = current.value; 60 | } 61 | } 62 | 63 | return minValue; 64 | } 65 | } 66 | 67 | let theStack = new Stack(); 68 | theStack.push(1); 69 | theStack.push(2); 70 | theStack.push(3); 71 | console.log(theStack.min()); 72 | -------------------------------------------------------------------------------- /5. Stack & Queue/3. Challenges/2. Valid Parenthesis.js: -------------------------------------------------------------------------------- 1 | const isValidParenthesis = (str) => { 2 | // Use a stack to store opening brackets 3 | const stack = []; 4 | 5 | // Map opening brackets to their closing counterparts 6 | const brackets = { 7 | "{": "}", 8 | "[": "]", 9 | "(": ")", 10 | }; 11 | 12 | // Loop through each character in the string 13 | for (let char of str) { 14 | // If it's an opening bracket, push it to the stack 15 | if (brackets[char]) { 16 | stack.push(char); 17 | } else { 18 | // If it's a closing bracket, check if it matches the top of the stack 19 | const top = stack.pop(); 20 | if (!top || brackets[top] !== char) { 21 | return false; 22 | } 23 | } 24 | } 25 | 26 | // After iterating, check if the stack is empty (all brackets were matched) 27 | return stack.length === 0; 28 | }; 29 | 30 | console.log(isValidParenthesis("(){}[]")); // true 31 | console.log(isValidParenthesis("([)]")); // false 32 | console.log(isValidParenthesis("()")); // true 33 | console.log(isValidParenthesis("(")); // false 34 | -------------------------------------------------------------------------------- /5. Stack & Queue/3. Challenges/3. Reverse String Using Stack.js: -------------------------------------------------------------------------------- 1 | function reverseString(str) { 2 | // Create an empty stack 3 | const stack = []; 4 | 5 | // Push each character of the string onto the stack 6 | for (let char of str) { 7 | stack.push(char); 8 | } 9 | 10 | // Initialize an empty string to store the reversed string 11 | let reversedStr = ""; 12 | 13 | // Pop characters from the stack and build the reversed string 14 | while (stack.length > 0) { 15 | reversedStr += stack.pop(); 16 | } 17 | 18 | // Return the reversed string 19 | return reversedStr; 20 | } 21 | 22 | const originalString = "hello world"; 23 | const reversedString = reverseString(originalString); 24 | console.log(reversedString); // Output: dlrow olleh 25 | -------------------------------------------------------------------------------- /6. Hash Table/1. Custom Hash Table/index.js: -------------------------------------------------------------------------------- 1 | class HashTable { 2 | constructor(size = 6) { 3 | this.keyMap = new Array(size); 4 | } 5 | 6 | _hashFunction(key) { 7 | let sum = 0; 8 | const PRIME_NUMBER = 31; 9 | 10 | for (let i = 0; i < Math.min(key.length, 100); i++) { 11 | const charCode = key.charCodeAt(0) - 96; 12 | sum = (sum * PRIME_NUMBER + charCode) % this.keyMap.length; 13 | } 14 | 15 | return sum; 16 | } 17 | 18 | set(key, value) { 19 | const index = this._hashFunction(key); 20 | if (!this.keyMap[index]) this.keyMap[index] = []; 21 | this.keyMap[index].push([key, value]); 22 | return this; 23 | } 24 | 25 | get(key) { 26 | const index = this._hashFunction(key); 27 | if (this.keyMap[index]) { 28 | for (let i = 0; i < this.keyMap[index].length; i++) { 29 | if (this.keyMap[index][i][0] === key) { 30 | return this.keyMap[index][i][1]; 31 | } 32 | } 33 | } 34 | return undefined; 35 | } 36 | 37 | getAllKeys() { 38 | const keys = []; 39 | for (let i = 0; i < this.keyMap.length; i++) { 40 | if (this.keyMap[i]) { 41 | for (let j = 0; j < this.keyMap[i].length; j++) { 42 | keys.push(this.keyMap[i][j][0]); 43 | } 44 | } 45 | } 46 | return keys; 47 | } 48 | 49 | getAllValues() { 50 | const values = []; 51 | for (let i = 0; i < this.keyMap.length; i++) { 52 | if (this.keyMap[i]) { 53 | for (let j = 0; j < this.keyMap[i].length; j++) { 54 | values.push(this.keyMap[i][j][1]); 55 | } 56 | } 57 | } 58 | return values; 59 | } 60 | } 61 | 62 | const phoneBook = new HashTable(); 63 | phoneBook.set("john", "555-333-444"); 64 | phoneBook.set("jordan", "222-444-666"); 65 | phoneBook.set("michel", "111-666-222"); 66 | console.log(phoneBook.get("jordan")); 67 | console.log(phoneBook.getAllValues()); 68 | console.log(phoneBook.getAllKeys()); 69 | -------------------------------------------------------------------------------- /6. Hash Table/2. Challenges/1. Word Instance Counter/index.js: -------------------------------------------------------------------------------- 1 | function wordCounter(text) { 2 | const lowerText = text.toLowerCase(); 3 | const wordMap = {}; 4 | const words = lowerText.split(/\s+/); 5 | 6 | for (const word of words) { 7 | if (word in wordMap) { 8 | wordMap[word]++; 9 | } else { 10 | wordMap[word] = 1; 11 | } 12 | } 13 | 14 | return wordMap; 15 | } 16 | 17 | const text = "Hello my name name name is huxn"; 18 | // { hello: 1, my: 1, name: 3, is: 1, huxn: 1 } 19 | const wordCounts = wordCounter(text); 20 | 21 | console.log(wordCounts); 22 | -------------------------------------------------------------------------------- /6. Hash Table/2. Challenges/2. Two Sum/index.js: -------------------------------------------------------------------------------- 1 | function twoSum(nums, target) { 2 | const numMap = {}; 3 | 4 | for (let i = 0; i < nums.length; i++) { 5 | const complement = target - nums[i]; 6 | if (complement in numMap && numMap[complement] !== i) { 7 | return [numMap[complement], i]; 8 | } 9 | numMap[nums[i]] = i; 10 | } 11 | 12 | return []; 13 | } 14 | 15 | const nums = [2, 7, 11, 15]; 16 | const target = 9; 17 | const result = twoSum(nums, target); 18 | console.log(result); // [0, 1] 19 | -------------------------------------------------------------------------------- /6. Hash Table/2. Challenges/3. Group Anagrams/index.js: -------------------------------------------------------------------------------- 1 | function groupAnagrams(strs) { 2 | const anagramMap = {}; 3 | 4 | for (const str of strs) { 5 | const sortedStr = str.split("").sort().join(""); 6 | 7 | if (sortedStr in anagramMap) { 8 | anagramMap[sortedStr].push(str); 9 | } else { 10 | anagramMap[sortedStr] = [str]; 11 | } 12 | } 13 | 14 | return Object.values(anagramMap); 15 | } 16 | 17 | const strs = ["eat", "tea", "tan", "ate", "nat", "bat"]; 18 | const groups = groupAnagrams(strs); 19 | 20 | console.log(groups); 21 | // Output: [["eat", "tea", "ate"], ["bat"], ["nat", "tan"]] 22 | -------------------------------------------------------------------------------- /7. Tree/1. 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 BST { 10 | constructor() { 11 | this.root = null; 12 | } 13 | 14 | insert(value) { 15 | const newNode = new Node(value); 16 | if (this.root === null) { 17 | this.root = newNode; 18 | return this; 19 | } 20 | 21 | let temp = this.root; 22 | while (true) { 23 | if (newNode.value === temp.value) return undefined; 24 | if (newNode.value < temp.value) { 25 | if (temp.left === null) { 26 | temp.left = newNode; 27 | return this; 28 | } else { 29 | temp = temp.left; 30 | } 31 | } else { 32 | if (temp.right === null) { 33 | temp.right = newNode; 34 | return this; 35 | } 36 | temp = temp.right; 37 | } 38 | } 39 | } 40 | 41 | includes(value) { 42 | if (!this.root) return false; 43 | 44 | let temp = this.root; 45 | while (temp) { 46 | if (value < temp.value) { 47 | temp = temp.left; 48 | } else if (value > temp.value) { 49 | temp = temp.right; 50 | } else if (value === temp.value) { 51 | return true; 52 | } 53 | } 54 | return false; 55 | } 56 | } 57 | 58 | const tree = new BST(); 59 | tree.insert(5); 60 | tree.insert(8); 61 | tree.insert(3); 62 | tree.insert(1); 63 | tree.insert(7); 64 | tree.insert(9); 65 | console.log(tree.includes(9)); 66 | -------------------------------------------------------------------------------- /7. Tree/2. Recursion/index.js: -------------------------------------------------------------------------------- 1 | // ------------------ Example 1 2 | function countDown(number) { 3 | if (number === 0) { 4 | console.log("And finally the stopping point! 🥂"); 5 | return; 6 | } 7 | 8 | console.log(number); 9 | countDown(number - 1); 10 | } 11 | 12 | countDown(5); 13 | 14 | // ------------------ Example 2 15 | function factorial(number) { 16 | if (number === 0) { 17 | return 1; 18 | } 19 | 20 | return number * factorial(number - 1); 21 | // return number === 0 ? 1 : number * factorial(number - 1); 22 | } 23 | 24 | console.log(factorial(4)); 25 | -------------------------------------------------------------------------------- /7. Tree/3. Tree Traversal/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 BST { 10 | constructor() { 11 | this.root = null; 12 | } 13 | 14 | insert(value) { 15 | const newNode = new Node(value); 16 | if (this.root === null) { 17 | this.root = newNode; 18 | return this; 19 | } 20 | 21 | let temp = this.root; 22 | while (true) { 23 | if (newNode.value === temp.value) return undefined; 24 | if (newNode.value < temp.value) { 25 | if (temp.left === null) { 26 | temp.left = newNode; 27 | return this; 28 | } else { 29 | temp = temp.left; 30 | } 31 | } else { 32 | if (temp.right === null) { 33 | temp.right = newNode; 34 | return this; 35 | } 36 | temp = temp.right; 37 | } 38 | } 39 | } 40 | 41 | dfs() { 42 | let current = this.root; 43 | let queue = []; 44 | let data = []; 45 | 46 | queue.push(current); 47 | 48 | while (queue.length) { 49 | current = queue.shift(); 50 | data.push(current.value); 51 | 52 | if (current.left) queue.push(current.left); 53 | if (current.right) queue.push(current.right); 54 | } 55 | return data; 56 | } 57 | 58 | dfsPreOrder(node = this.root, data = []) { 59 | if (node === null) return data; 60 | console.log("--------", data); 61 | 62 | data.push(node.value); 63 | if (node.left) this.dfsPreOrder(node.left, data); 64 | if (node.right) this.dfsPreOrder(node.right, data); 65 | return data; 66 | } 67 | 68 | dfsPostOrder(node = this.root, data = []) { 69 | if (node === null) return data; 70 | if (node.left) this.dfsPostOrder(node.left, data); 71 | if (node.right) this.dfsPostOrder(node.right, data); 72 | data.push(node.value); 73 | return data; 74 | } 75 | 76 | dfsInOrder(node = this.root, data = []) { 77 | if (node === null) return data; 78 | this.dfsInOrder(node.left, data); 79 | data.push(node.value); 80 | this.dfsInOrder(node.right, data); 81 | return data; 82 | } 83 | } 84 | 85 | const tree = new BST(); 86 | tree.insert(5); 87 | tree.insert(8); 88 | tree.insert(3); 89 | tree.insert(1); 90 | tree.insert(7); 91 | tree.insert(9); 92 | console.log(tree.dfs()); 93 | console.log(tree.dfsPreOrder()); 94 | console.log(tree.dfsPostOrder()); 95 | console.log(tree.dfsInOrder()); 96 | -------------------------------------------------------------------------------- /8. Graphs/index.js: -------------------------------------------------------------------------------- 1 | class Graph { 2 | constructor() { 3 | this.adjacencyList = {}; 4 | } 5 | 6 | addVertex(vtx) { 7 | if (!this.adjacencyList[vtx]) { 8 | this.adjacencyList[vtx] = []; 9 | return true; 10 | } 11 | return false; 12 | } 13 | 14 | addEdge(vtx1, vtx2) { 15 | if (this.adjacencyList[vtx1] && this.adjacencyList[vtx2]) { 16 | this.adjacencyList[vtx1].push(vtx2); 17 | this.adjacencyList[vtx2].push(vtx1); 18 | return true; 19 | } 20 | return false; 21 | } 22 | 23 | removeEdge(vtx1, vtx2) { 24 | if (this.adjacencyList[vtx1] && this.adjacencyList[vtx2]) { 25 | this.adjacencyList[vtx1] = this.adjacencyList[vtx2].filter( 26 | (v) => v !== vtx2 27 | ); 28 | 29 | this.adjacencyList[vtx2] = this.adjacencyList[vtx2].filter( 30 | (v) => v !== vtx1 31 | ); 32 | return true; 33 | } 34 | return false; 35 | } 36 | 37 | removeVertex(vtx) { 38 | if (!this.adjacencyList[vtx]) return undefined; 39 | 40 | for (let neighbor of this.adjacencyList[vtx]) { 41 | this.adjacencyList[neighbor] = this.adjacencyList[neighbor].filter( 42 | (v) => v !== vtx 43 | ); 44 | } 45 | 46 | delete this.adjacencyList[vtx]; 47 | return this; 48 | } 49 | } 50 | 51 | let g = new Graph(); 52 | // ---------------- 53 | // g.addVertex("A"); 54 | // g.addVertex("B"); 55 | // g.addEdge("A", "B"); 56 | // ---------------- 57 | 58 | // ---------------- 59 | // g.addVertex("A"); 60 | // g.addVertex("B"); 61 | // g.addVertex("C"); 62 | // g.addEdge("A", "B"); 63 | // g.addEdge("B", "C"); 64 | // g.addEdge("C", "A"); 65 | // console.log(g); 66 | // g.removeEdge("A", "B"); 67 | // console.log(g); 68 | // ---------------- 69 | 70 | g.addVertex("A"); 71 | g.addVertex("B"); 72 | g.addVertex("C"); 73 | g.addVertex("D"); 74 | g.addEdge("A", "B"); 75 | g.addEdge("A", "C"); 76 | g.addEdge("A", "D"); 77 | g.addEdge("B", "D"); 78 | g.addEdge("C", "D"); 79 | console.log(g); 80 | g.removeVertex("D"); 81 | console.log(g); 82 | -------------------------------------------------------------------------------- /9. Sorting Algo/1. Bubble Sort/index.js: -------------------------------------------------------------------------------- 1 | function bubbleSort(arr) { 2 | for (let i = arr.length - 1; i > 0; i--) { 3 | for (let j = 0; j < i; j++) { 4 | if (arr[j] > arr[j + 1]) { 5 | let temp = arr[j]; 6 | arr[j] = arr[j + 1]; 7 | arr[j + 1] = temp; 8 | } 9 | } 10 | } 11 | return arr; 12 | } 13 | 14 | const myArr = [4, 2, 6, 5, 1, 3]; 15 | const res = bubbleSort(myArr); 16 | console.log(res); 17 | -------------------------------------------------------------------------------- /9. Sorting Algo/2. Selection Sort/index.js: -------------------------------------------------------------------------------- 1 | function selectionSort(arr) { 2 | for (let i = 0; i < arr.length; i++) { 3 | let minIndex = i; 4 | 5 | for (let j = i + 1; j < arr.length; j++) { 6 | if (arr[j] < arr[minIndex]) { 7 | minIndex = j; 8 | } 9 | } 10 | 11 | if (i !== minIndex) { 12 | let temp = arr[i]; 13 | arr[i] = arr[minIndex]; 14 | arr[minIndex] = temp; 15 | 16 | // SHORTHAND 👇 17 | // [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]; 18 | } 19 | } 20 | return arr; 21 | } 22 | 23 | const myArr = [4, 2, 6, 5, 1, 3]; 24 | const res = selectionSort(myArr); 25 | console.log(res); 26 | -------------------------------------------------------------------------------- /9. Sorting Algo/3. Insertion Sort/index.js: -------------------------------------------------------------------------------- 1 | function insertionSort(arr) { 2 | for (let i = 1; i < arr.length; i++) { 3 | let key = arr[i]; 4 | let j = i - 1; 5 | 6 | while (j >= 0 && arr[j] > key) { 7 | arr[j + 1] = arr[j]; 8 | j--; 9 | } 10 | 11 | arr[j + 1] = key; 12 | } 13 | 14 | return arr; 15 | } 16 | 17 | const unsortedArray = [5, 2, 4, 6, 1, 3]; 18 | const sortedArray = insertionSort(unsortedArray); 19 | console.log(sortedArray); 20 | -------------------------------------------------------------------------------- /9. Sorting Algo/4. Merge Sort/index.js: -------------------------------------------------------------------------------- 1 | function mergeSort(arr) { 2 | if (arr.length <= 1) return arr; 3 | 4 | const middle = Math.floor(arr.length / 2); 5 | const left = arr.slice(0, middle); 6 | const right = arr.slice(middle); 7 | 8 | return merge(mergeSort(left), mergeSort(right)); 9 | } 10 | 11 | function merge(left, right) { 12 | const result = []; 13 | let i = 0; 14 | let j = 0; 15 | 16 | while (i < left.length && j < right.length) { 17 | if (left[i] < right[j]) { 18 | result.push(left[i]); 19 | i++; 20 | } else { 21 | result.push(right[j]); 22 | j++; 23 | } 24 | } 25 | 26 | result.push(...left.slice(i)); 27 | result.push(...right.slice(j)); 28 | 29 | return result; 30 | } 31 | 32 | const unsortedArray = [38, 27, 43, 3, 9, 82, 10]; 33 | const sortedArray = mergeSort(unsortedArray); 34 | console.log(sortedArray); 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HuXn-WebDev/Data-Structures-Algorithms/6fe2054fc39b03db998e41d48b2fc2dd001250da/README.md -------------------------------------------------------------------------------- /thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HuXn-WebDev/Data-Structures-Algorithms/6fe2054fc39b03db998e41d48b2fc2dd001250da/thumb.png --------------------------------------------------------------------------------