From 10e7cd6430a3cc7bcc6945c7c6cf9ac5218292b9 Mon Sep 17 00:00:00 2001 From: Zero-1016 Date: Wed, 1 Jul 2026 10:19:20 +0900 Subject: [PATCH 1/6] vailid-anagram --- valid-anagram/Zero-1016.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 valid-anagram/Zero-1016.ts diff --git a/valid-anagram/Zero-1016.ts b/valid-anagram/Zero-1016.ts new file mode 100644 index 0000000000..e473d4ff73 --- /dev/null +++ b/valid-anagram/Zero-1016.ts @@ -0,0 +1,26 @@ +/** + * 242. Valid Anagram + * Given two strings s and t, return true if t is an anagram of s, and false otherwise. + * + * 시간복잡도: O(n) + * 공간복잡도: O(n) + */ +function isAnagram(s: string, t: string): boolean { + if (s.length !== t.length) return false; + + const sMap = new Map(); + const tMap = new Map(); + + // 문자열 s와 t를 순회하면서 각 문자의 빈도수를 계산 + for (let i = 0; i < s.length; i++) { + sMap.set(s[i], (sMap.get(s[i]) || 0) + 1); + tMap.set(t[i], (tMap.get(t[i]) || 0) + 1); + } + + // 문자열 s와 t의 빈도수를 비교 + for (const [key, value] of sMap) { + if (value !== tMap.get(key) || !tMap.has(key)) return false; + } + + return true; +} From caed9d06ab5bc2c3cf23fec001eb5644ee98f499 Mon Sep 17 00:00:00 2001 From: Zero-1016 Date: Fri, 3 Jul 2026 00:27:46 +0900 Subject: [PATCH 2/6] climbing-stairs --- climbing-stairs/Zero-1016.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 climbing-stairs/Zero-1016.ts diff --git a/climbing-stairs/Zero-1016.ts b/climbing-stairs/Zero-1016.ts new file mode 100644 index 0000000000..d708cb82e5 --- /dev/null +++ b/climbing-stairs/Zero-1016.ts @@ -0,0 +1,19 @@ +/** + * 시간 복잡도 O(n) + * 공간 복잡도 O(n) + */ +function climbStairs(n: number): number { + // NOTE: n이 1일 경우 바로 종료 + if (n === 1) return 1; + + const dp = new Array(n).fill(0); + + dp[0] = 1; + dp[1] = 2; + + for (let i = 2; i < dp.length; i++) { + dp[i] = dp[i - 1] + dp[i - 2]; + } + + return dp[dp.length - 1]; +} From 4065c60d17db3ae983909caf6c4a56c84345793b Mon Sep 17 00:00:00 2001 From: Zero-1016 Date: Fri, 3 Jul 2026 00:38:50 +0900 Subject: [PATCH 3/6] product-of-array-except-self --- product-of-array-except-self/Zero-1016.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 product-of-array-except-self/Zero-1016.ts diff --git a/product-of-array-except-self/Zero-1016.ts b/product-of-array-except-self/Zero-1016.ts new file mode 100644 index 0000000000..a52974b31e --- /dev/null +++ b/product-of-array-except-self/Zero-1016.ts @@ -0,0 +1,23 @@ +/** + * 시간복잡도 O(n) + * 공간복잡도 O(n) + */ +function productExceptSelf(nums: number[]): number[] { + const n_length = nums.length; + const result = new Array(n_length).fill(1); + + // NOTE: 왼쪽 -> 오른쪽, 오른쪽 -> 왼쪽 순회하면서 값을 누적함. + let left = 1; + for (let i = 0; i < n_length; i++) { + result[i] *= left; + left *= nums[i]; + } + + let right = 1; + for (let i = n_length - 1; i >= 0; i--) { + result[i] *= right; + right *= nums[i]; + } + + return result; +} From e68b4cdca2ddecd44a986a0a93bb281ae0867c81 Mon Sep 17 00:00:00 2001 From: Zero-1016 Date: Fri, 3 Jul 2026 00:47:39 +0900 Subject: [PATCH 4/6] 3sum --- 3sum/Zero-1016.ts | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 3sum/Zero-1016.ts diff --git a/3sum/Zero-1016.ts b/3sum/Zero-1016.ts new file mode 100644 index 0000000000..31d12a22ef --- /dev/null +++ b/3sum/Zero-1016.ts @@ -0,0 +1,43 @@ +/** + * 시간 복잡도 O(n²) + * 공간 복잡도 O(log n) + * + * 접근: 오름차순 정렬 + 투 포인터 + * - 기준 인덱스 i를 고정하고, left = i + 1, right = 끝에서 탐색 + * - 정렬된 상태에서 같은 값을 건너뛰는 방식으로 중복 제거 (Set 불필요) + */ +function threeSum(nums: number[]): number[][] { + const result: number[][] = []; + nums.sort((a, b) => a - b); // 오름차순 정렬 + + for (let i = 0; i < nums.length - 2; i++) { + // 기준 숫자가 이전과 같으면 동일한 조합이 나오므로 건너뜀 + if (i > 0 && nums[i] === nums[i - 1]) continue; + + // 최적화: 기준 숫자가 양수면 뒤의 숫자들도 모두 양수 → 합이 0 불가능 + if (nums[i] > 0) break; + + let left = i + 1; + let right = nums.length - 1; + + while (left < right) { + const sum = nums[i] + nums[left] + nums[right]; + + if (sum === 0) { + result.push([nums[i], nums[left], nums[right]]); + + while (left < right && nums[left] === nums[left + 1]) left++; + while (left < right && nums[right] === nums[right - 1]) right--; + + left++; + right--; + } else if (sum < 0) { + left++; + } else { + right--; + } + } + } + + return result; +} From 08e356aa45c19c0189317ad416d5faebd097bbbf Mon Sep 17 00:00:00 2001 From: Zero-1016 Date: Fri, 3 Jul 2026 10:58:49 +0900 Subject: [PATCH 5/6] validate-binary-search-tree --- validate-binary-search-tree/Zero-1016.ts | 40 ++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 validate-binary-search-tree/Zero-1016.ts diff --git a/validate-binary-search-tree/Zero-1016.ts b/validate-binary-search-tree/Zero-1016.ts new file mode 100644 index 0000000000..b909a89138 --- /dev/null +++ b/validate-binary-search-tree/Zero-1016.ts @@ -0,0 +1,40 @@ +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; + } +} +type Frame = { + node: TreeNode | null; + min: number; + max: number; +}; + +/** + * 반복적 DFS로 각 노드가 부모 노드가 정한 값 범위 (min, max) 안에 있는지 검사한다. + * - 왼쪽 자식으로 내려가면 상한(max)이 현재 노드 값으로 좁아지고, + * - 오른쪽 자식으로 내려가면 하한(min)이 현재 노드 값으로 좁아진다. + * + * 시간 복잡도: O(n) — 모든 노드를 한 번씩 방문 + * 공간 복잡도: O(n) — 최악의 경우 스택 크기 (평균적으로는 O(h)) + */ +function isValidBST(root: TreeNode | null): boolean { + const stack: Frame[] = [{ node: root, min: -Infinity, max: Infinity }]; + + while (stack.length > 0) { + const { node, min, max } = stack.pop()!; + if (!node) continue; + + // NOTE 부모 노드들이 정한 범위를 벗어나면 유효한 BST가 아니다. + if (node.val <= min || node.val >= max) return false; + + stack.push({ node: node.left, min, max: node.val }); + stack.push({ node: node.right, min: node.val, max }); + } + + return true; +} From aea363abd55bb25007fa0d3a368e869f1b5bb9b5 Mon Sep 17 00:00:00 2001 From: Zero-1016 Date: Fri, 3 Jul 2026 11:01:43 +0900 Subject: [PATCH 6/6] =?UTF-8?q?refactor:=20has=20=EA=B2=80=EC=82=AC=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- valid-anagram/Zero-1016.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/valid-anagram/Zero-1016.ts b/valid-anagram/Zero-1016.ts index e473d4ff73..8cb23de94d 100644 --- a/valid-anagram/Zero-1016.ts +++ b/valid-anagram/Zero-1016.ts @@ -19,7 +19,7 @@ function isAnagram(s: string, t: string): boolean { // 문자열 s와 t의 빈도수를 비교 for (const [key, value] of sMap) { - if (value !== tMap.get(key) || !tMap.has(key)) return false; + if (value !== tMap.get(key)) return false; } return true;