diff --git a/alexgoni/102_Binary_Tree_Level_Order_Traversal.js b/alexgoni/102_Binary_Tree_Level_Order_Traversal.js new file mode 100644 index 0000000..893aefd --- /dev/null +++ b/alexgoni/102_Binary_Tree_Level_Order_Traversal.js @@ -0,0 +1,37 @@ +// 😢 + +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @return {number[][]} + */ +var levelOrder = function (root) { + if (!root) return []; + + const result = []; + const q = [root]; + + while (q.length > 0) { + const level = []; + const size = q.length; + + for (let i = 0; i < size; i++) { + const node = q.shift(); + level.push(node.val); + + if (node.left) q.push(node.left); + if (node.right) q.push(node.right); + } + + result.push(level); + } + + return result; +}; diff --git a/alexgoni/139_Word_Break.js b/alexgoni/139_Word_Break.js new file mode 100644 index 0000000..601f052 --- /dev/null +++ b/alexgoni/139_Word_Break.js @@ -0,0 +1,23 @@ +// 😢 + +/** + * @param {string} s + * @param {string[]} wordDict + * @return {boolean} + */ +var wordBreak = function (s, wordDict) { + const wordSet = new Set(wordDict); + const dp = Array.from({ length: s.length + 1 }).fill(false); + dp[0] = true; + + for (let i = 1; i <= s.length; i++) { + for (let j = 0; j < i; j++) { + if (dp[j] && wordSet.has(s.slice(j, i))) { + dp[i] = true; + break; + } + } + } + + return dp[s.length]; +}; diff --git a/alexgoni/150_Evaluate_Reverse_Polish_Notation.js b/alexgoni/150_Evaluate_Reverse_Polish_Notation.js new file mode 100644 index 0000000..454d27d --- /dev/null +++ b/alexgoni/150_Evaluate_Reverse_Polish_Notation.js @@ -0,0 +1,48 @@ +// /** +// * @param {string[]} tokens +// * @return {number} +// */ +// var evalRPN = function(tokens) { +// let i = 0; + +// while(tokens.length > 1) { +// if(isNaN(tokens[i])) { +// let temp; + +// if(tokens[i] === "+") temp = Number(tokens[i-2]) + Number(tokens[i-1]); +// if(tokens[i] === "-") temp = Number(tokens[i-2]) - Number(tokens[i-1]); +// if(tokens[i] === "*") temp = Number(tokens[i-2]) * Number(tokens[i-1]); +// if(tokens[i] === "/") temp = Math.trunc(Number(tokens[i-2]) / Number(tokens[i-1])); + +// tokens.splice(i-2, 3, temp); +// i = 0; +// } + +// i++; +// } + +// return +tokens[0]; +// }; + +/** + * @param {string[]} tokens + * @return {number} + */ +var evalRPN = function (tokens) { + const stack = []; + + for (let token of tokens) { + if (!isNaN(token)) stack.push(Number(token)); + else { + const b = stack.pop(); + const a = stack.pop(); + + if (token === "+") stack.push(a + b); + if (token === "-") stack.push(a - b); + if (token === "*") stack.push(a * b); + if (token === "/") stack.push(Math.trunc(a / b)); + } + } + + return stack.pop(); +}; diff --git a/alexgoni/1584_Min_Cost_to_Connect_All_Points.js b/alexgoni/1584_Min_Cost_to_Connect_All_Points.js new file mode 100644 index 0000000..9882b6d --- /dev/null +++ b/alexgoni/1584_Min_Cost_to_Connect_All_Points.js @@ -0,0 +1,39 @@ +// 😢 + +/** + * @param {number[][]} points + * @return {number} + */ +var minCostConnectPoints = function (points) { + const n = points.length; + const visited = Array(n).fill(false); + const minDist = Array(n).fill(Infinity); + minDist[0] = 0; + let result = 0; + + for (let i = 0; i < n; i++) { + let currMin = Infinity; + let currNode = -1; + + for (let j = 0; j < n; j++) { + if (!visited[j] && minDist[j] < currMin) { + currMin = minDist[j]; + currNode = j; + } + } + + visited[currNode] = true; + result += currMin; + + for (let j = 0; j < n; j++) { + if (!visited[j]) { + const cost = + Math.abs(points[currNode][0] - points[j][0]) + + Math.abs(points[currNode][1] - points[j][1]); + minDist[j] = Math.min(minDist[j], cost); + } + } + } + + return result; +}; diff --git a/alexgoni/207_Course_Schedule.js b/alexgoni/207_Course_Schedule.js new file mode 100644 index 0000000..2423e36 --- /dev/null +++ b/alexgoni/207_Course_Schedule.js @@ -0,0 +1,34 @@ +// 😢 + +/** + * @param {number} numCourses + * @param {number[][]} prerequisites + * @return {boolean} + */ +var canFinish = function (numCourses, prerequisites) { + const graph = Array.from({ length: numCourses }, () => []); + for (const [a, b] of prerequisites) { + graph[b].push(a); + } + + const visited = Array(numCourses).fill(0); + + const hasCycle = (cource) => { + if (visited[cource] === 1) return true; + if (visited[cource] === 2) return false; + + visited[cource] = 1; + for (const neighbor of graph[cource]) { + if (hasCycle(neighbor)) return true; + } + visited[cource] = 2; + + return false; + }; + + for (let i = 0; i < numCourses; i++) { + if (hasCycle(i)) return false; + } + + return true; +}; diff --git a/alexgoni/213_House_Robber_ll.js b/alexgoni/213_House_Robber_ll.js new file mode 100644 index 0000000..f348bb7 --- /dev/null +++ b/alexgoni/213_House_Robber_ll.js @@ -0,0 +1,30 @@ +/** + * @param {number[]} nums + * @return {number} + */ +var rob = function (nums) { + if (nums.length <= 3) return Math.max(...nums); + + const firstNums = nums.slice(0, nums.length - 1); + const secondNums = nums.slice(1); + const firstDp = [firstNums[0], firstNums[1]]; + const secondDp = [secondNums[0], secondNums[1]]; + + for (let i = 2; i < firstNums.length; i++) { + if (i === 2) firstDp[i] = firstDp[0] + firstNums[i]; + else firstDp[i] = Math.max(firstDp[i - 2], firstDp[i - 3]) + firstNums[i]; + } + + for (let i = 2; i < secondNums.length; i++) { + if (i === 2) secondDp[i] = secondDp[0] + secondNums[i]; + else + secondDp[i] = Math.max(secondDp[i - 2], secondDp[i - 3]) + secondNums[i]; + } + + return Math.max( + firstDp[firstNums.length - 1], + firstDp[firstNums.length - 2], + secondDp[secondNums.length - 1], + secondDp[secondNums.length - 2] + ); +}; diff --git a/alexgoni/215_Kth_Largest_Element_in_an_Array.js b/alexgoni/215_Kth_Largest_Element_in_an_Array.js new file mode 100644 index 0000000..e82715b --- /dev/null +++ b/alexgoni/215_Kth_Largest_Element_in_an_Array.js @@ -0,0 +1,96 @@ +// 😢 + +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ +var findKthLargest = function (nums, k) { + const heap = new MaxBinaryHeap(); + + for (const num of nums) { + heap.insert(num); + } + + for (let i = 0; i < k; i++) { + const extractedValue = heap.extractMax(); + if (i === k - 1) return extractedValue; + } +}; + +class MaxBinaryHeap { + constructor() { + this.values = []; + } + + insert(value) { + this.values.push(value); + this.#bubbleUp(); + + return this.values; + } + + extractMax() { + const extractedValue = this.values[0]; + const poppedValue = this.values.pop(); + + if (this.values.length === 0) return extractedValue; + + this.values[0] = poppedValue; + this.#sinkDown(); + + return extractedValue; + } + + #bubbleUp() { + let currentIndex = this.values.length - 1; + const currentValue = this.values[currentIndex]; + + while (currentIndex > 0) { + const parentIndex = Math.floor((currentIndex - 1) / 2); + const parentValue = this.values[parentIndex]; + + if (parentValue >= currentValue) break; + + this.values[parentIndex] = currentValue; + this.values[currentIndex] = parentValue; + + currentIndex = parentIndex; + } + } + + #sinkDown() { + let currentIndex = 0; + const currentValue = this.values[currentIndex]; + const length = this.values.length; + + while (true) { + let leftChildIndex = currentIndex * 2 + 1; + let rightChildIndex = currentIndex * 2 + 2; + let leftChildValue, rightChildValue; + let swapWith = null; + + if (leftChildIndex < length) { + leftChildValue = this.values[leftChildIndex]; + if (leftChildValue > currentValue) swapWith = leftChildIndex; + } + + if (rightChildIndex < length) { + rightChildValue = this.values[rightChildIndex]; + if ( + (!swapWith && rightChildValue > currentValue) || + (swapWith && rightChildValue > leftChildValue) + ) { + swapWith = rightChildIndex; + } + } + + if (!swapWith) break; + + this.values[currentIndex] = this.values[swapWith]; + this.values[swapWith] = currentValue; + + currentIndex = swapWith; + } + } +} diff --git a/alexgoni/235_Lowest_Common_Ancestor_of_a_Binary_Search_Tree.js b/alexgoni/235_Lowest_Common_Ancestor_of_a_Binary_Search_Tree.js new file mode 100644 index 0000000..d2c48bc --- /dev/null +++ b/alexgoni/235_Lowest_Common_Ancestor_of_a_Binary_Search_Tree.js @@ -0,0 +1,27 @@ +// 😢 + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @param {TreeNode} p + * @param {TreeNode} q + * @return {TreeNode} + */ +var lowestCommonAncestor = function (root, p, q) { + if (p.val < root.val && q.val < root.val) { + return lowestCommonAncestor(root.left, p, q); + } + + if (p.val > root.val && q.val > root.val) { + return lowestCommonAncestor(root.right, p, q); + } + + return root; +}; diff --git a/alexgoni/56_Merge_Intervals.js b/alexgoni/56_Merge_Intervals.js new file mode 100644 index 0000000..9b74555 --- /dev/null +++ b/alexgoni/56_Merge_Intervals.js @@ -0,0 +1,22 @@ +/** + * @param {number[][]} intervals + * @return {number[][]} + */ +var merge = function (intervals) { + const result = []; + intervals.sort((a, b) => a[0] - b[0]); + + let i = 0; + while (i < intervals.length - 1) { + if (intervals[i][1] >= intervals[i + 1][0]) { + intervals.splice(i, 2, [ + intervals[i][0], + Math.max(intervals[i][1], intervals[i + 1][1]), + ]); + } else { + i++; + } + } + + return intervals; +}; diff --git a/alexgoni/572_Subtree_of_Another_Tree.js b/alexgoni/572_Subtree_of_Another_Tree.js new file mode 100644 index 0000000..893eaf4 --- /dev/null +++ b/alexgoni/572_Subtree_of_Another_Tree.js @@ -0,0 +1,30 @@ +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @param {TreeNode} subRoot + * @return {boolean} + */ +var isSubtree = function (root, subRoot) { + if (!root) return false; + + if (isSameTree(root, subRoot)) return true; + + return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot); +}; + +function isSameTree(root1, root2) { + if (!root1 && !root2) return true; + if (!root1 || !root2) return false; + if (root1.val !== root2.val) return false; + + return ( + isSameTree(root1.left, root2.left) && isSameTree(root1.right, root2.right) + ); +}