diff --git a/alien-dictionary/hyer0705.ts b/alien-dictionary/hyer0705.ts new file mode 100644 index 000000000..8b7b8363a --- /dev/null +++ b/alien-dictionary/hyer0705.ts @@ -0,0 +1,63 @@ +export class Solution { + alienOrder(words: string[]): string { + const indegree = new Map(); + const graph = new Map>(); + + for (const word of words) { + for (const ch of word) { + if (graph.has(ch)) continue; + graph.set(ch, new Set()); + indegree.set(ch, 0); + } + } + + for (let i = 0; i < words.length - 1; i++) { + const word1 = words[i]; + const word2 = words[i + 1]; + + let pointer = 0; + while (pointer < word1.length && pointer < word2.length && word1[pointer] === word2[pointer]) { + pointer++; + } + + if (pointer < word1.length && pointer === word2.length) { + return ""; + } + + if (pointer < word1.length && pointer < word2.length) { + const neighbors = graph.get(word1[pointer])!; + if (!neighbors.has(word2[pointer])) { + neighbors.add(word2[pointer]); + indegree.set(word2[pointer], (indegree.get(word2[pointer]) || 0) + 1); + } + } + } + + const queue: string[] = []; + const result: string[] = []; + + for (const [ch, degree] of indegree) { + if (degree === 0) { + queue.push(ch); + } + } + + while (queue.length > 0) { + const current = queue.shift()!; + result.push(current); + + for (const neighbor of graph.get(current) || []) { + indegree.set(neighbor, (indegree.get(neighbor) || 0) - 1); + if (indegree.get(neighbor) === 0) { + queue.push(neighbor); + } + } + } + + if (indegree.size === result.length) { + return result.join(""); + } + + return ""; + } +} diff --git a/construct-binary-tree-from-preorder-and-inorder-traversal/hyer0705.ts b/construct-binary-tree-from-preorder-and-inorder-traversal/hyer0705.ts new file mode 100644 index 000000000..de5b9ede2 --- /dev/null +++ b/construct-binary-tree-from-preorder-and-inorder-traversal/hyer0705.ts @@ -0,0 +1,64 @@ +/** + * Definition for a binary tree node. + * 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) + * } + * } + */ + +// 37ms +// Time Complexity: O(n^2), n: 노드의 수 +// Space Complexity: O(h), h: 트리의 높이 +function buildTree(preorder: number[], inorder: number[]): TreeNode | null { + if (preorder.length === 0 || inorder.length === 0) return null; + + const root = preorder[0]; + + const rootIdx = inorder.findIndex((el) => el === root); + + const leftInorder = inorder.slice(0, rootIdx); + const leftPreorder = preorder.slice(1, leftInorder.length + 1); + + const rightInorder = inorder.slice(rootIdx + 1); + const rightPreorder = preorder.slice(leftInorder.length + 1); + + const rootNode = new TreeNode(root); + + rootNode.left = buildTree(leftPreorder, leftInorder); + rootNode.right = buildTree(rightPreorder, rightInorder); + + return rootNode; +} + +// 3ms +// Time Complexity: O(n), n: 노드의 수 +// Space Complexity: O(n), n: 노드의 수 +function buildTree(preorder: number[], inorder: number[]): TreeNode | null { + if (preorder.length === 0 || inorder.length === 0) return null; + + const indexMap = new Map(); + inorder.forEach((node, idx) => indexMap.set(node, idx)); + + const build = (preStart: number, preEnd: number, inStart: number, inEnd: number): TreeNode | null => { + if (preStart > preEnd || inStart > inEnd) return null; + + const rootVal = preorder[preStart]; + const rootIdx = indexMap.get(rootVal); + + const leftSize = rootIdx - inStart; + + const root = new TreeNode(rootVal); + root.left = build(preStart + 1, preStart + leftSize, inStart, rootIdx - 1); + root.right = build(preStart + leftSize + 1, preEnd, rootIdx + 1, inEnd); + + return root; + }; + + return build(0, preorder.length - 1, 0, inorder.length - 1); +} diff --git a/longest-palindromic-substring/hyer0705.ts b/longest-palindromic-substring/hyer0705.ts new file mode 100644 index 000000000..d4a14fa38 --- /dev/null +++ b/longest-palindromic-substring/hyer0705.ts @@ -0,0 +1,31 @@ +// Time Complexity: O(n^2), n: s의 길이 +// Space Complexity: O(1) +function longestPalindrome(s: string): string { + const expandAroundCenter = (s: string, left: number, right: number): [number, number] => { + while (left >= 0 && right < s.length && s[left] === s[right]) { + left--; + right++; + } + + return [left + 1, right - 1]; + }; + + let longest = ""; + for (let i = 0; i < s.length; i++) { + const [s1, e1] = expandAroundCenter(s, i, i); + const [s2, e2] = expandAroundCenter(s, i, i + 1); + + const odd = e1 - s1 + 1; + const even = e2 - s2 + 1; + + if (longest.length < odd) { + longest = s.slice(s1, e1 + 1); + } + + if (longest.length < even) { + longest = s.slice(s2, e2 + 1); + } + } + + return longest; +} diff --git a/rotate-image/hyer0705.ts b/rotate-image/hyer0705.ts new file mode 100644 index 000000000..f2cde9ddc --- /dev/null +++ b/rotate-image/hyer0705.ts @@ -0,0 +1,20 @@ +/** + Do not return anything, modify matrix in-place instead. + */ +// Time Complexity: O(n^2), n: matrix의 한 변의 길이 +// Space Complexity: O(1) +function rotate(matrix: number[][]): void { + const n = matrix.length; + + for (let i = 0; i < n; i++) { + for (let j = i + 1; j < n; j++) { + [matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]]; + } + } + + for (let i = 0; i < n; i++) { + for (let j = 0; j < Math.floor(n / 2); j++) { + [matrix[i][j], matrix[i][n - j - 1]] = [matrix[i][n - j - 1], matrix[i][j]]; + } + } +} diff --git a/subtree-of-another-tree/hyer0705.ts b/subtree-of-another-tree/hyer0705.ts new file mode 100644 index 000000000..699a22386 --- /dev/null +++ b/subtree-of-another-tree/hyer0705.ts @@ -0,0 +1,33 @@ +/** + * Definition for a binary tree node. + * 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) + * } + * } + */ + +// Time Complexity: O(m * n), m: root의 노드 수, n: subRoot의 노드 수 +// Space Complexity: O(h), h: root의 높이 +function isSubtree(root: TreeNode | null, subRoot: TreeNode | null): boolean { + if (!root) return false; + + const isSameTree = (root: TreeNode | null, subRoot: TreeNode | null): boolean => { + if (!root && !subRoot) return true; + if (!root || !subRoot) return false; + if (root.val !== subRoot.val) return false; + + return isSameTree(root.left, subRoot.left) && isSameTree(root.right, subRoot.right); + }; + + const current = isSameTree(root, subRoot); + const left = isSubtree(root.left, subRoot); + const right = isSubtree(root.right, subRoot); + + return current || left || right; +}