diff --git a/binary-tree-level-order-traversal/Jeehay28.ts b/binary-tree-level-order-traversal/Jeehay28.ts new file mode 100644 index 000000000..feb54fa59 --- /dev/null +++ b/binary-tree-level-order-traversal/Jeehay28.ts @@ -0,0 +1,42 @@ + class TreeNode { + val: number + left: TreeNode | null + right: TreeNode | null + constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + this.val = (val===undefined ? 0 : val) + this.left = (left===undefined ? null : left) + this.right = (right===undefined ? null : right) + } + } + + +// TC: O(n) +// SC: O(n) +function levelOrder(root: TreeNode | null): number[][] { + if (!root) return []; + + const result: number[][] = []; + const queue: TreeNode[] = [root]; + + while (queue.length > 0) { + const values: number[] = []; + const level = queue.length; + + for (let i = 0; i < level; i++) { + const node = queue.shift()!; + values.push(node.val); + + if (node.left) { + queue.push(node.left); + } + + if (node.right) { + queue.push(node.right); + } + } + + result.push(values); + } + + return result; +} diff --git a/counting-bits/Jeehay28.ts b/counting-bits/Jeehay28.ts new file mode 100644 index 000000000..a29e996cf --- /dev/null +++ b/counting-bits/Jeehay28.ts @@ -0,0 +1,17 @@ +// TC: O(n) +// SC: O(n) +function countBits(n: number): number[] { + const dp: number[] = []; + dp[0] = 0; + + for (let i = 0; i <= n; i++) { + dp[i] = dp[i >> 1] + (i & 1); + } + + // The number of 1s in the quotient (i >> 1) + number of 1s in the remainder (i & 1) + // dp[i >> 1]: number of 1's in Math.floor(i / 2) + // i & 1: 1 if i is odd, 0 if even + + return dp; +} + diff --git a/house-robber-ii/Jeehay28.ts b/house-robber-ii/Jeehay28.ts new file mode 100644 index 000000000..9f80c1b32 --- /dev/null +++ b/house-robber-ii/Jeehay28.ts @@ -0,0 +1,20 @@ +// TC: O(n) +// SC: O(1) +function rob(nums: number[]): number { + if (nums.length === 1) return nums[0]; + + const robHouse = (start: number, end: number) => { + let prevSum = 0; + let prevPrevSum = 0; + + for (let i = start; i <= end; i++) { + const temp = Math.max(prevSum, prevPrevSum + nums[i]); + prevPrevSum = prevSum; + prevSum = temp; + } + + return prevSum; + }; + + return Math.max(robHouse(0, nums.length - 2), robHouse(1, nums.length - 1)); +} diff --git a/word-search-ii/Jeehay28.ts b/word-search-ii/Jeehay28.ts new file mode 100644 index 000000000..e0d9c0154 --- /dev/null +++ b/word-search-ii/Jeehay28.ts @@ -0,0 +1,86 @@ +// TC: O(K × L + M × N × 4^L) +// SC: O(K × L + L) +// K: num of words +// L: length of the longest word + +function findWords(board: string[][], words: string[]): string[] { + const result: string[] = []; + const root: TrieNode = buildTrie(words); + const rows = board.length; + const cols = board[0].length; + + function backtrack(row: number, col: number, node: TrieNode) { + const char = board[row][col]; + const nextNode = node[char] as TrieNode; + + if (!nextNode) return; + + const word = nextNode["$"]; + if (typeof word === "string") { + result.push(word); + delete nextNode["$"]; // avoid duplicate + } + + board[row][col] = ""; // mark as visited + + const directions = [ + [1, 0], + [-1, 0], + [0, 1], + [0, -1], + ]; + + for (const [dx, dy] of directions) { + const newRow = row + dx; + const newCol = col + dy; + + if ( + newRow >= 0 && + newRow < rows && + newCol >= 0 && + newCol < cols && + board[newRow][newCol] !== "$" + ) { + backtrack(newRow, newCol, nextNode); + } + } + + board[row][col] = char; + } + + for (let r = 0; r < rows; r++) { + for (let c = 0; c < cols; c++) { + backtrack(r, c, root); + } + } + + return result; +} + +// Trie +// { +// "e": { +// "a": { +// "t": { +// "#": "eat" +// } +// } +// } +// } + +type TrieNode = { + [key: string]: TrieNode | string; +}; + +function buildTrie(words: string[]): TrieNode { + const root: TrieNode = {}; + for (const word of words) { + let node = root; + for (const char of word) { + if (!node[char]) node[char] = {}; + node = node[char] as TrieNode; + } + node["$"] = word; // end of word + } + return root; +}