diff --git a/binary-tree-level-order-traversal/HoonDongKang.ts b/binary-tree-level-order-traversal/HoonDongKang.ts new file mode 100644 index 000000000..4965c5826 --- /dev/null +++ b/binary-tree-level-order-traversal/HoonDongKang.ts @@ -0,0 +1,41 @@ +/** + * [Problem]: [102] Binary Tree Level Order Traversal + * (https://leetcode.com/problems/binary-tree-level-order-traversal/description/) + */ + +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; + } +} + +// 시간복잡도 O(n) +// 공간복잡도 O(n) +function levelOrder(root: TreeNode | null): number[][] { + if (!root) return []; + + const result: number[][] = []; + const queue: TreeNode[] = [root]; + + while (queue.length > 0) { + const level = queue.length; + const values: number[] = []; + + 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/HoonDongKang.ts b/counting-bits/HoonDongKang.ts new file mode 100644 index 000000000..be82c1d8c --- /dev/null +++ b/counting-bits/HoonDongKang.ts @@ -0,0 +1,32 @@ +/** + * [Problem]: [338] Counting Bits + * (https://leetcode.com/problems/counting-bits/description/) + */ +function countBits(n: number): number[] { + //시간복잡도 O(n) + //공간복잡도 O(n) + function dpFunc(n: number): number[] { + const dp = new Array(n + 1).fill(0); + let offset = 1; + + for (let i = 1; i <= n; i++) { + if (offset * 2 === i) { + offset = i; + } + + dp[i] = 1 + dp[i - offset]; + } + + return dp; + } + + //시간복잡도 O(n) + //공간복잡도 O(n) + function optimizedFunc(n: number): number[] { + const dp = new Array(n + 1).fill(0); + for (let i = 0; i <= n; i++) { + dp[i] = dp[i >> 1] + (i & 1); + } + return dp; + } +} diff --git a/house-robber-ii/HoonDongKang.ts b/house-robber-ii/HoonDongKang.ts new file mode 100644 index 000000000..347274b4b --- /dev/null +++ b/house-robber-ii/HoonDongKang.ts @@ -0,0 +1,50 @@ +/** + * [Problem]: [213] House Robber II + * (https://leetcode.com/problems/house-robber-ii/description/) + */ +function rob(nums: number[]): number { + //시간복잡도 O(n) + //공간복잡도 O(n) + function memoizationFunc(nums: number[]): number { + const memo = new Map(); + const length = nums.length; + + function dfs(idx: number, first = false) { + const key = `${idx}_${first}`; + if (memo.has(key)) return memo.get(key)!; + + if (idx === length - 1) return first ? 0 : nums[idx]; + if (idx >= length) return 0; + if (idx === 0) { + const result = Math.max(nums[0] + dfs(2, true), dfs(1, false)); + memo.set(key, result); + return result; + } + + const result = Math.max(nums[idx] + dfs(idx + 2, first), dfs(idx + 1, first)); + memo.set(key, result); + return result; + } + + return dfs(0); + } + + //시간복잡도 O(n) + //공간복잡도 O(1) + function dpFunc(nums: number[]): number { + if (nums.length === 1) return nums[0]; + + function dp(start: number, end: number) { + let prev = 0; + let cur = 0; + + for (let i = start; i < end; i++) { + [prev, cur] = [cur, Math.max(prev + nums[i], cur)]; + } + + return cur; + } + + return Math.max(dp(0, nums.length - 1), dp(1, nums.length)); + } +} diff --git a/meeting-rooms-ii/HoonDongKang.ts b/meeting-rooms-ii/HoonDongKang.ts new file mode 100644 index 000000000..fc10e05ea --- /dev/null +++ b/meeting-rooms-ii/HoonDongKang.ts @@ -0,0 +1,44 @@ +/** + * [Problem]: [919] Meeting Rooms II + * (https://www.lintcode.com/problem/919/) + */ + +export class Interval { + start: number; + end: number; + constructor(start: number, end: number) { + this.start = start; + this.end = end; + } +} + +// 시간복잡도 O(n log n) +// 공간복잡도 O(n) +export class Solution { + /** + * @param intervals: an array of meeting time intervals + * @return: the minimum number of conference rooms required + */ + minMeetingRooms(intervals: Interval[]): number { + if (intervals.length === 0) return 0; + + const starts = intervals.map((i) => i.start).sort((a, b) => a - b); + const ends = intervals.map((i) => i.end).sort((a, b) => a - b); + + let count = 0; + let maxCount = 0; + let endIdx = 0; + + for (let i = 0; i < intervals.length; i++) { + if (starts[i] < ends[endIdx]) { + count++; + } else { + endIdx++; + } + + maxCount = Math.max(maxCount, count); + } + + return maxCount; + } +} diff --git a/word-search-ii/HoonDongKang.ts b/word-search-ii/HoonDongKang.ts new file mode 100644 index 000000000..a38f1b53a --- /dev/null +++ b/word-search-ii/HoonDongKang.ts @@ -0,0 +1,74 @@ +/** + * [Problem]: [212] Word Search II + * (https://leetcode.com/problems/word-search-ii/) + */ + +class TrieNode { + children: Map = new Map(); + word: string | null = null; +} + +//시간복잡도 O(m * n * 4^s) +//공간복잡도 O(trie 저장 공간(word * length) + result) +function findWords(board: string[][], words: string[]): string[] { + const result: string[] = []; + const rows = board.length; + const cols = board[0].length; + + const root = new TrieNode(); + for (const word of words) { + let node = root; + + for (const char of word) { + if (!node.children.has(char)) { + node.children.set(char, new TrieNode()); + } + node = node.children.get(char)!; + } + + node.word = word; + } + + const dfs = (i: number, j: number, node: TrieNode) => { + const char = board[i][j]; + const next = node.children.get(char); + if (!next) return; + + if (next.word) { + result.push(next.word); + next.word = null; + } + + board[i][j] = "#"; + + const directions = [ + [0, 1], + [1, 0], + [0, -1], + [-1, 0], + ]; + + for (const [dx, dy] of directions) { + const ni = i + dx; + const nj = j + dy; + + if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && board[ni][nj] !== "#") { + dfs(ni, nj, next); + } + } + + board[i][j] = char; + + if (next.children.size === 0) { + node.children.delete(char); + } + }; + + for (let i = 0; i < rows; i++) { + for (let j = 0; j < cols; j++) { + dfs(i, j, root); + } + } + + return result; +}