From 493745cf7f64764cc29e0d179f960f16e81f75db Mon Sep 17 00:00:00 2001 From: mmyeon Date: Wed, 19 Mar 2025 11:10:00 +0900 Subject: [PATCH 1/4] add solution : 572. Subtree of Another Tree --- subtree-of-another-tree/mmyeon.ts | 61 +++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 subtree-of-another-tree/mmyeon.ts diff --git a/subtree-of-another-tree/mmyeon.ts b/subtree-of-another-tree/mmyeon.ts new file mode 100644 index 000000000..adc7ec19e --- /dev/null +++ b/subtree-of-another-tree/mmyeon.ts @@ -0,0 +1,61 @@ +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; + } +} + +/** + * + * 접근 방법 : + * - DFS로 루트 노드를 찾은 뒤, 하위 트리가 동일한 트리인지 확인하기 + * + * 시간복잡도 : O(n * m) + * - n = root 트리 노드의 개수 + * - m = subRoot 트리 노드의 개수 + * - 루트 노드 찾기 위해서 O(n) + * - 동일 트리 체크하기 위해서 O(m) + * + * 공간복잡도 : O(n + m) + * - n = root 트리 높이 + * - m = subRoot 트리 높이 + * - dfs 탐색 최대 깊이 O(n) + * - isSameTree 탐색 최대 깊이 O(m) + * + */ +function isSubtree(root: TreeNode | null, subRoot: TreeNode | null): boolean { + if (!root) return false; + + const isSameTree = ( + node: TreeNode | null, + subNode: TreeNode | null + ): boolean => { + // 두 노드가 null이면 동일한 트리 + if (!node && !subNode) return true; + // 한 노드만 null이면 다른 트리 + if (!node || !subNode) return false; + // 값이 다르면 다른 트리 + if (node.val !== subNode.val) return false; + + // 값이 같으니까 왼쪽, 오른쪽 하위 트리도 비교 + return ( + isSameTree(node.left, subNode.left) && + isSameTree(node.right, subNode.right) + ); + }; + + // 루트 노드 찾기 + const dfs = (node: TreeNode | null): boolean => { + if (!node) return false; + // 동일한 트리인지 확인 + if (isSameTree(node, subRoot)) return true; + // 왼쪽이나 오른쪽 추가 탐색 진행 + return dfs(node.left) || dfs(node.right); + }; + + return dfs(root); +} From 9e2b07d5832b47ddda647310369a660f3f40129e Mon Sep 17 00:00:00 2001 From: mmyeon Date: Thu, 20 Mar 2025 15:25:07 +0900 Subject: [PATCH 2/4] add solution : 98. Validate Binary Search Tree --- validate-binary-search-tree/mmyeon.ts | 29 +++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 validate-binary-search-tree/mmyeon.ts diff --git a/validate-binary-search-tree/mmyeon.ts b/validate-binary-search-tree/mmyeon.ts new file mode 100644 index 000000000..f66fb1e50 --- /dev/null +++ b/validate-binary-search-tree/mmyeon.ts @@ -0,0 +1,29 @@ +/** + * + * 접근 방법 : + * - 이진 탐색 트리의 특징(왼쪽 자식 노드 < 부모 노드 < 오른쪽 자식 노드)을 이용하여 문제 풀기 + * - 부모 노드 값, 최상위 루트 노드 값을 모두 고려해야 하니까 min, max로 값의 범위 지정하기 + * + * 시간복잡도 : O(n) + * - n = root 트리 노드의 개수 + * - 모든 노드 탐색 : O(n) + * + * 공간복잡도 : O(h) + * - h = root 트리 높이 + * - 재귀 호출이 트리 높이만큼 발생함 + * - 치우친 트리의 경우 h = O(n) + * + */ +function isValidBST(root: TreeNode | null): boolean { + function helper(node: TreeNode | null, min: number, max: number): boolean { + if (!node) return true; + + if (node.val <= min || node.val >= max) return false; + + return ( + helper(node.left, min, node.val) && helper(node.right, node.val, max) + ); + } + + return helper(root, -Infinity, Infinity); +} From e7bd7718dcddfde87a1d547758dfd554e9680509 Mon Sep 17 00:00:00 2001 From: mmyeon Date: Thu, 20 Mar 2025 16:36:22 +0900 Subject: [PATCH 3/4] add solution : 5. Longest Palindromic Substring --- longest-palindromic-substring/mmyeon.ts | 35 +++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 longest-palindromic-substring/mmyeon.ts diff --git a/longest-palindromic-substring/mmyeon.ts b/longest-palindromic-substring/mmyeon.ts new file mode 100644 index 000000000..cfc3dfe9a --- /dev/null +++ b/longest-palindromic-substring/mmyeon.ts @@ -0,0 +1,35 @@ +/** + * + * 접근 방법 : + * - 팰린드롬은 좌우 대칭 문자열을 찾아야 한다. + * - 문자열 중심이 1개(홀수)일 때와 2개(짝수)일 때 고려해서 팰린드롬을 확장하며 긴 문자열을 리턴한다. + * + * 시간복잡도 : O(n^2) + * - n = s 문자열 길이 + * - 동일 문자인 경우 for문과 while문에서 2번 순회 발생 O(n) + * + * 공간복잡도 : O(1) + * - 고정된 변수만 사용 + * + */ +function longestPalindrome(s: string): string { + let result = ""; + + function expandFromCenter(start: number, end: number) { + while (start >= 0 && end < s.length && s[start] === s[end]) { + start--; + end++; + } + return s.slice(start + 1, end); + } + + for (let i = 0; i < s.length; i++) { + const oddPalindrome = expandFromCenter(i, i); + if (oddPalindrome.length > result.length) result = oddPalindrome; + + const evenPalindrome = expandFromCenter(i, i + 1); + if (evenPalindrome.length > result.length) result = evenPalindrome; + } + + return result; +} From 2a7d9f5f46a7b3cab525db4c8061d0accb6e292b Mon Sep 17 00:00:00 2001 From: mmyeon Date: Fri, 21 Mar 2025 14:49:40 +0900 Subject: [PATCH 4/4] add solution : 48. Rotate Image --- rotate-image/mmyeon.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 rotate-image/mmyeon.ts diff --git a/rotate-image/mmyeon.ts b/rotate-image/mmyeon.ts new file mode 100644 index 000000000..1dcde104b --- /dev/null +++ b/rotate-image/mmyeon.ts @@ -0,0 +1,29 @@ +/** + Do not return anything, modify matrix in-place instead. + */ + +/** + * + * 접근 방법 : + * - 1. matrix 순회하면서 대각선 기준으로 위쪽만 행과 열 값 바꾼다. + * - 2. 행 기준으로 reverse한다. + * + * 시간복잡도 : O(n^2) + * - n = matrix 행, 열 크기 + * - matrix 순회 O(n^2) + * + * 공간복잡도 : O(1) + * - 추가 배열 사용하지 않음 + * + */ +function rotate(matrix: number[][]): void { + for (let i = 0; i < matrix.length; i++) { + for (let j = i + 1; j < matrix.length; j++) { + [matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]]; + } + } + + for (let i = 0; i < matrix.length; i++) { + matrix[i].reverse(); + } +}