diff --git a/binary-tree-level-order-traversal/HC-kang.ts b/binary-tree-level-order-traversal/HC-kang.ts new file mode 100644 index 000000000..3ed222c69 --- /dev/null +++ b/binary-tree-level-order-traversal/HC-kang.ts @@ -0,0 +1,57 @@ +// 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; +// } +// } + +/** + * https://leetcode.com/problems/binary-tree-level-order-traversal + * T.C. O(n) + * S.C. O(n) + */ +function levelOrder(root: TreeNode | null): number[][] { + const result: number[][] = []; + function dfs(node: TreeNode | null, level: number) { + if (!node) return; + if (!result[level]) result[level] = []; + result[level].push(node.val); + dfs(node.left, level + 1); + dfs(node.right, level + 1); + } + dfs(root, 0); + return result; +} + +/** + * bfs + * T.C. O(n) + * S.C. O(n) + */ +function levelOrder(root: TreeNode | null): number[][] { + const result: number[][] = []; + if (!root) return result; + + const queue: TreeNode[] = [root]; + let start = 0; + + while (queue[start]) { + const levelSize = queue.length - start; + const currentLevel: number[] = []; + + for (let i = 0; i < levelSize; i++) { + const node = queue[start++]; + currentLevel.push(node.val); + if (node.left) queue.push(node.left); + if (node.right) queue.push(node.right); + } + + result.push(currentLevel); + } + + return result; +} diff --git a/house-robber-ii/HC-kang.ts b/house-robber-ii/HC-kang.ts new file mode 100644 index 000000000..63d9d6a6a --- /dev/null +++ b/house-robber-ii/HC-kang.ts @@ -0,0 +1,26 @@ +/** + * https://leetcode.com/problems/house-robber-ii + * T.C. O(n) + * S.C. O(1) + */ +function rob(nums: number[]): number { + if (nums.length === 1) return nums[0]; + if (nums.length === 2) return Math.max(nums[0], nums[1]); + if (nums.length === 3) return Math.max(nums[0], nums[1], nums[2]); + + function robHelper(nums: number[]): number { + let prev = 0; + let curr = 0; + for (let i = 0; i < nums.length; i++) { + const temp = curr; + curr = Math.max(prev + nums[i], curr); + prev = temp; + } + return curr; + } + + const robFirst = robHelper(nums.slice(0, nums.length - 1)); + const robLast = robHelper(nums.slice(1)); + + return Math.max(robFirst, robLast); +} diff --git a/meeting-rooms-ii/HC-kang.ts b/meeting-rooms-ii/HC-kang.ts new file mode 100644 index 000000000..9069a3c60 --- /dev/null +++ b/meeting-rooms-ii/HC-kang.ts @@ -0,0 +1,21 @@ +/** + * https://leetcode.com/problems/meeting-rooms-ii + * T.C. O(nlogn) + * S.C. O(n) + */ +function minMeetingRooms(intervals: number[][]): number { + const starts = intervals.map((interval) => interval[0]).sort((a, b) => a - b); + const ends = intervals.map((interval) => interval[1]).sort((a, b) => a - b); + + let rooms = 0; + let endIdx = 0; + for (let i = 0; i < starts.length; i++) { + if (starts[i] < ends[endIdx]) { + rooms++; + } else { + endIdx++; + } + } + + return rooms; +} diff --git a/reverse-bits/HC-kang.ts b/reverse-bits/HC-kang.ts new file mode 100644 index 000000000..e4d78c5cc --- /dev/null +++ b/reverse-bits/HC-kang.ts @@ -0,0 +1,13 @@ +/** + * https://leetcode.com/problems/reverse-bits + * T.C. O(1) + * S.C. O(1) + */ +function reverseBits(n: number): number { + let result = 0; + for (let i = 0; i < 32; i++) { + result = (result << 1) | (n & 1); + n >>= 1; + } + return result >>> 0; +} diff --git a/word-search-ii/HC-kang.ts b/word-search-ii/HC-kang.ts new file mode 100644 index 000000000..e818593c3 --- /dev/null +++ b/word-search-ii/HC-kang.ts @@ -0,0 +1,62 @@ +/** + * https://leetcode.com/problems/word-search-ii + * T.C. O(W * L + M * N * 4^L) W: number of words, L: mean length of words, M: rows, N: cols + * S.C. O(W * L) + */ +function findWords(board: string[][], words: string[]): string[] { + const root = new TrieNode(); + for (const word of words) { + let node = root; + for (const char of word) { + if (!node.children[char]) { + node.children[char] = new TrieNode(); + } + node = node.children[char]; + } + node.word = word; + node.isEnd = true; + } + + const result = new Set(); + const rows = board.length; + const cols = board[0].length; + + function dfs(row: number, col: number, node: TrieNode): void { + if (row < 0 || row >= rows) return; + if (col < 0 || col >= cols) return; + if (!board[row][col]) return; + if (!node.children[board[row][col]]) return; + + const char = board[row][col]; + const currNode = node.children[char]; + + if (currNode.isEnd) { + result.add(currNode.word); + } + + board[row][col] = '#'; + + dfs(row + 1, col, currNode); + dfs(row - 1, col, currNode); + dfs(row, col + 1, currNode); + dfs(row, col - 1, currNode); + + board[row][col] = char; + } + + for (let i = 0; i < rows; i++) { + for (let j = 0; j < cols; j++) { + dfs(i, j, root); + } + } + + return Array.from(result); +} + +class TrieNode { + constructor( + public children: Record = {}, + public word: string = '', + public isEnd: boolean = false + ) {} +}