diff --git a/binary-tree-level-order-traversal/Jeehay28.js b/binary-tree-level-order-traversal/Jeehay28.js new file mode 100644 index 000000000..0a86cf8a4 --- /dev/null +++ b/binary-tree-level-order-traversal/Jeehay28.js @@ -0,0 +1,37 @@ +// ✅ Time Complexity: O(n), where n is the number of nodes in the tree +// ✅ Space Complexity: O(n) + +/** + * 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 []; + + let output = []; + let queue = [root]; + + while (queue.length > 0) { + let values = []; + + const lengthQueue = queue.length; + + for (let i = 0; i < lengthQueue; i++) { + const node = queue.shift(); + values.push(node.val); + if (node.left) queue.push(node.left); + if (node.right) queue.push(node.right); + } + output.push(values); + } + return output; +}; + diff --git a/counting-bits/Jeehay28.js b/counting-bits/Jeehay28.js new file mode 100644 index 000000000..0eca13201 --- /dev/null +++ b/counting-bits/Jeehay28.js @@ -0,0 +1,51 @@ +// ✅ Time Complexity: O(n) +// ✅ Space Complexity: O(n) + +/** + * @param {number} n + * @return {number[]} + */ +var countBits = function (n) { + // dp[i] = 1 + dp[i - MSB] + // MSB(Most Significant Bit) + + let dp = new Array(n + 1).fill(0); + let msb = 1; + + for (let i = 1; i <= n; i++) { + if (msb * 2 === i) { + msb = i; + } + + dp[i] = 1 + dp[i - msb]; + } + + return dp; +}; + +// ✅ Time Complexity: O(n * logn) +// ✅ Space Complexity: O(n) + +/** + * @param {number} n + * @return {number[]} + */ +// var countBits = function (n) { +// let result = [0]; +// const count = (num) => { +// let cnt = 0; +// while (num !== 0) { +// cnt += num % 2; +// num = Math.floor(num / 2); +// } +// return cnt; +// }; + +// for (let i = 1; i <= n; i++) { +// const temp = count(i); +// result.push(temp); +// } + +// return result; +// }; + diff --git a/house-robber-ii/Jeehay28.js b/house-robber-ii/Jeehay28.js new file mode 100644 index 000000000..63fd0f09f --- /dev/null +++ b/house-robber-ii/Jeehay28.js @@ -0,0 +1,35 @@ +// ✅ Time Complexity: O(n) +// ✅ Space Complexity: O(1) + +/** + * @param {number[]} nums + * @return {number} + */ +var rob = function (nums) { + // Edge case: If there's only one house, return its value + if (nums.length === 1) return nums[0]; + + // helper function + const robHouses = (start, end) => { + // prev1: stores the maximum money robbed up to the previous house. + // prev2: stores the maximum money robbed up to the house before the previous house. + let prev1 = 0, + prev2 = 0; + + for (let i = start; i <= end; i++) { + let temp = Math.max(prev1, prev2 + nums[i]); + + prev2 = prev1; + + prev1 = temp; + } + + return prev1; + }; + + // Excluding the last house: robHouses(0, nums.length - 2) + // Excluding the first house: robHouses(1, nums.length - 1) + + return Math.max(robHouses(0, nums.length - 2), robHouses(1, nums.length - 1)); +}; + diff --git a/word-search-ii/Jeehay28.js b/word-search-ii/Jeehay28.js new file mode 100644 index 000000000..8220a9c38 --- /dev/null +++ b/word-search-ii/Jeehay28.js @@ -0,0 +1,104 @@ +// const words = ["oath", "pea", "eat", "rain"]; +// const trie = buildTrie(words); + +// Trie in JavaScript Object Notation: +// { +// "o": { "a": { "t": { "h": { "word": "oath" } } } }, +// "p": { "e": { "a": { "word": "pea" } } }, +// "e": { "a": { "t": { "word": "eat" } } }, +// "r": { "a": { "i": { "n": { "word": "rain" } } } } +// } + +class TrieNode { + constructor() { + this.children = {}; // Stores child nodes (next characters) + this.word = null; // Stores the word when a full word is formed + } +} + +const buildTrie = (words) => { + let root = new TrieNode(); // Create the root node + + for (const word of words) { + // Iterate over each word + let node = root; + + for (const char of word) { + // Iterate over each character in the word + if (!node.children[char]) { + node.children[char] = new TrieNode(); // Create node if missing + } + node = node.children[char]; // Move to the next node + } + + node.word = word; // Store word at the end node + } + + return root; +}; + +// ✅ Time Complexity: O(N * L + M * 4^L) +// ✅ Space Complexity: O(N * L + M) + +// N represents the number of words in the words array. +// L represents the maximum length of a word in the words array. +// M represents the total number of cells on the board, which is the product of the number of rows and columns: M = rows × cols + +/** + * @param {character[][]} board + * @param {string[]} words + * @return {string[]} + */ +var findWords = function (board, words) { + const root = buildTrie(words); + const result = new Set(); // To store found words + const rows = board.length, + cols = board[0].length; + + const dfs = (node, r, c) => { + if ( + r < 0 || + c < 0 || + r >= rows || + c >= cols || + !node.children[board[r][c]] + ) { + return; + } + + const char = board[r][c]; + node = node.children[char]; // Move to the next Trie node + + if (node.word) { + // If a word is found at this node + result.add(node.word); // Add it to the result set + node.word = null; // Avoid duplicate results + } + + board[r][c] = "#"; // Temporarily mark visited cell + + // Explore all 4 directions + dfs(node, r + 1, c); + dfs(node, r - 1, c); + dfs(node, r, c + 1); + dfs(node, r, c - 1); + + board[r][c] = char; // Restore the original character + + // 🔥 Remove node if it has no children (prune Trie) + if (Object.keys(node.children).length === 0) { + delete node.children[char]; + } + }; + + for (let r = 0; r < rows; r++) { + for (let c = 0; c < cols; c++) { + if (root.children[board[r][c]]) { + dfs(root, r, c); + } + } + } + + return Array.from(result); +}; +