From aabda78f5dee5f4147a380bc0513a384fd9e9cea Mon Sep 17 00:00:00 2001 From: NovaCat Date: Mon, 9 Nov 2026 21:13:28 +0900 Subject: [PATCH 01/21] 20261109 Resolved: Contains Duplicate #217 --- contains-duplicate/novacat25.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 contains-duplicate/novacat25.ts diff --git a/contains-duplicate/novacat25.ts b/contains-duplicate/novacat25.ts new file mode 100644 index 0000000000..ba5f14aeb3 --- /dev/null +++ b/contains-duplicate/novacat25.ts @@ -0,0 +1,27 @@ +/* + 시간 복잡도(Time Complexity): 평균 O(n) + 공간 복잡도(Space Complexity): 평균 O(n) + 풀이 알고리즘: JS의 HashMap / Map 이용 + + 풀이 History + 1트: 예전에 JS의 find() 메서드를 이용해 풀었을 때에는 TLE에 걸리기 일쑤였으니, JS 배열을 정렬(Quick Sort)하고 Binary Search로 일관된 정렬 시간을 확보하자!(X) + 2트: 이 문제에 정렬(sort) 과정이 필요한가? -> X. 따라서 탐색에 훨씬 유리한 자료구조를 찾아서 푸는 게 낫다고 판단함. + 3트: Map/HashMap을 이용해 Key 기반의 빠른 탐색 및 저장으로 풀자 +*/ + +const containsDuplicate = (nums: number[]): boolean => { + let answer = false + const set = new Set() + + for (let i = 0; i < nums.length; i++) { + const currentNum = nums[i] + if (set.has(currentNum)) { + answer = true + break + } else { + set.add(currentNum) + } + } + + return answer +} From 947a3d54c3393b05fe2998d8aeddc1ea8d2c2628 Mon Sep 17 00:00:00 2001 From: NovaCat Date: Tue, 10 Nov 2026 01:05:42 +0900 Subject: [PATCH 02/21] Resolved: Two Sum #219 --- two-sum/novacat25.ts | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 two-sum/novacat25.ts diff --git a/two-sum/novacat25.ts b/two-sum/novacat25.ts new file mode 100644 index 0000000000..5b77d90946 --- /dev/null +++ b/two-sum/novacat25.ts @@ -0,0 +1,31 @@ +/* + 시간 복잡도(Time Complexity): 평균 O(n) + 공간 복잡도(Space Complexity): 평균 O(n) + 풀이 알고리즘: JS의 HashMap / Map 이용 + + 풀이 History + 1트: 완전 탐색을 이용해 정답은 맞췄으나, Time Complexity가 O(n²) + 2트: HasyMap을 통해 Key - value 플로를 응용하여 O(n)으로 단축 완료 +*/ + +const twoSum = (nums: number[], target: number): number[] => { + const map: Map = new Map() + const arr = [0, 0] + + for (let i = 0; i < nums.length; i++) { + const currentNum = nums[i] + const anotherPair = target - currentNum + + if (map.has(anotherPair)) { + // map.has로 값을 가지고 있음이 확정되어 있으므로 non-null assertion을 통해 값 강제 + arr[0] = map.get(anotherPair)! + arr[1] = i + + break + } else { + map.set(currentNum, i) + } + } + + return arr +} From 524bd76903ee1054fbd8540df44590f87f46d7a8 Mon Sep 17 00:00:00 2001 From: NovaCat Date: Tue, 10 Nov 2026 14:13:20 +0900 Subject: [PATCH 03/21] Resolved: Top K Frequent Elements#237 --- top-k-frequent-elements/novacat25.ts | 49 ++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 top-k-frequent-elements/novacat25.ts diff --git a/top-k-frequent-elements/novacat25.ts b/top-k-frequent-elements/novacat25.ts new file mode 100644 index 0000000000..bac8930c40 --- /dev/null +++ b/top-k-frequent-elements/novacat25.ts @@ -0,0 +1,49 @@ +/* +공간 복잡도: O(n) +시간 복잡도: O(n) +풀이: nums의 length만큼 버킷을 생성하여 Bucket Sort 적용 후 빈도가 높은 순서대로 k개의 숫자를 선택한다. +풀이 History +1차: HashMap + Max Heap을 이용해 k개의 숫자를 선택하는 방식으로 구현하였다.(O(nlogk) 시간 복잡도) 문제 조건 상 시간 복잡도가 O(nlogn) 이하로 나와야 하므로 2차에서 Bucket Sort를 적용하여 O(n) 시간 복잡도로 구현하였다. +2차: 아래의 코드대로 Bucket Sort를 적용하여 k개의 숫자를 선택하는 방식으로 구현하였다.(O(n) 시간 복잡도) +*/ +const getBucketSort = (freqArr: number[][], n: number) => { + const buckets: number[][] = Array.from({ length: n + 1 }, () => []) + + // Put array elements in different buckets + for (let i = 0; i < freqArr.length; i++) { + const [num, freq] = freqArr[i] + buckets[freq].push(num) + } + + return buckets +} + +const topKFrequent = (nums: number[], k: number): number[] => { + const answerArr: number[] = [] + const entryArr: number[][] = [] + + const numberMap = new Map() + + for (const val of nums) { + const count = (numberMap.get(val) || 0) + 1 + numberMap.set(val, count) + } + + for (const entry of numberMap.entries()) { + entryArr.push(entry) + } + + const bucketArr = getBucketSort(entryArr, nums.length) + + for (let i = bucketArr.length - 1; i >= 0; i--) { + for (const num of bucketArr[i]) { + answerArr.push(num) + + if (answerArr.length === k) { + return answerArr + } + } + } + + return answerArr +} From a3fdeced42c75828d4735cbbe56708427242ffb0 Mon Sep 17 00:00:00 2001 From: NovaCat Date: Tue, 10 Nov 2026 14:50:49 +0900 Subject: [PATCH 04/21] Modify: contains-duplicate --- contains-duplicate/novacat25.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/contains-duplicate/novacat25.ts b/contains-duplicate/novacat25.ts index ba5f14aeb3..83aaa4800f 100644 --- a/contains-duplicate/novacat25.ts +++ b/contains-duplicate/novacat25.ts @@ -4,24 +4,22 @@ 풀이 알고리즘: JS의 HashMap / Map 이용 풀이 History - 1트: 예전에 JS의 find() 메서드를 이용해 풀었을 때에는 TLE에 걸리기 일쑤였으니, JS 배열을 정렬(Quick Sort)하고 Binary Search로 일관된 정렬 시간을 확보하자!(X) + 1트: 예전에 JS의 find() 메서드를 이용해 풀었을 때에는 TLE에 걸리기 일쑤였으니, JS 배열을 정렬(Quick Sort)하고 Binary Search로 일관된 정렬 시간을 확보하자!(X) -> 비효율적인 정렬 코스트로 TLE가 발생하여 틀렸다. 2트: 이 문제에 정렬(sort) 과정이 필요한가? -> X. 따라서 탐색에 훨씬 유리한 자료구조를 찾아서 푸는 게 낫다고 판단함. 3트: Map/HashMap을 이용해 Key 기반의 빠른 탐색 및 저장으로 풀자 */ const containsDuplicate = (nums: number[]): boolean => { - let answer = false const set = new Set() for (let i = 0; i < nums.length; i++) { const currentNum = nums[i] if (set.has(currentNum)) { - answer = true - break + return true } else { set.add(currentNum) } } - return answer + return false } From ea34956ef42a1e04fc1856c37b3631c83f22557a Mon Sep 17 00:00:00 2001 From: NovaCat Date: Tue, 10 Nov 2026 16:26:12 +0900 Subject: [PATCH 05/21] Resolved: Longest Consecutive Sequence #240 --- longest-consecutive-sequence/novacat25.ts | 36 +++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 longest-consecutive-sequence/novacat25.ts diff --git a/longest-consecutive-sequence/novacat25.ts b/longest-consecutive-sequence/novacat25.ts new file mode 100644 index 0000000000..f2acdc8213 --- /dev/null +++ b/longest-consecutive-sequence/novacat25.ts @@ -0,0 +1,36 @@ +/* +시간 복잡도(Time Complexity): 평균 O(n) +공간 복잡도(Space Complexity): 평균 O(n) +풀이 알고리즘: JS의 Hash Set 이용 + +풀이 History +1트: Hash Set을 떠올렸으나, for(const val of st) 부분에서 불필요한 부분을 탐색하여 TLE가 터졌다. (X) +2트: [...st]를 이용해 Set을 Array로 변환 후, for(const val of setArr)로 탐색하여 시간 복잡도를 개선했다. (O(n) 시간 복잡도) + +기타: Duplicate identifier 'longestConsecutive' 에러가 발생하는 듯하여 novacatLongestConsecutive라는 이름으로 함수를 변경함. +*/ + +const novacatLongestConsecutive = (nums: number[]): number => { + const st = new Set() + let result = 0 + + for (const val of nums) { + st.add(val) + } + + const setArr = [...st] + for (const val of setArr) { + if (!st.has(val - 1)) { + let cur = val + let cnt = 0 + while (st.has(cur)) { + cur++ + cnt++ + } + + result = Math.max(result, cnt) + } + } + + return result +} From 9bba1b72f9fdb140a204c73e4e82e45f3092d4ce Mon Sep 17 00:00:00 2001 From: NovaCat Date: Tue, 10 Nov 2026 17:04:01 +0900 Subject: [PATCH 06/21] Resolved: House Robber #264 --- house-robber/noavacat25.ts | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 house-robber/noavacat25.ts diff --git a/house-robber/noavacat25.ts b/house-robber/noavacat25.ts new file mode 100644 index 0000000000..48d392d027 --- /dev/null +++ b/house-robber/noavacat25.ts @@ -0,0 +1,30 @@ +/* +시간 복잡도: O(n) +공간 복잡도: O(1) +풀이 알고리즘: DP(Dynamic Programming) 이용 (Space-Optimised DP) + +해설: dp[i] = max(dp[i-2] + nums[i], dp[i-1]) 로 점화식을 세울 수 있다. +dp[i-2]와 dp[i-1]만 있으면 dp[i]를 구할 수 있으므로, dp 배열을 만들지 않고 두 개의 변수(secondLast, last)만으로도 구현 가능하다. + +점화식: dp[i] = max(dp[i−2] + nums[i], dp[i−1]) +Dynamic Programming 기법에 의해, secondLast와 last를 다음 Iteration에서 재사용할 수 있도록 저장하여 공간 최적화(Space-Optimisation)를 활용할 수 있다. +*/ +const novacat25_rob = (nums: number[]): number => { + const n = nums.length + + if (n === 0) return 0 + if (n === 1) return nums[0] + + let secondLast = 0 + let last = nums[0] + + let result = -1 + + for (let i = 1; i < n; i++) { + result = Math.max(nums[i] + secondLast, last) + secondLast = last + last = result + } + + return result +} From 8bc8abd5fb58807d8c94f10d8ed3f4203f3d1588 Mon Sep 17 00:00:00 2001 From: NovaCat Date: Tue, 10 Nov 2026 17:05:24 +0900 Subject: [PATCH 07/21] Fix: name lint failed(House Robber #264) --- house-robber/noavacat25.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/house-robber/noavacat25.ts b/house-robber/noavacat25.ts index 48d392d027..21dc25ec78 100644 --- a/house-robber/noavacat25.ts +++ b/house-robber/noavacat25.ts @@ -9,7 +9,7 @@ dp[i-2]와 dp[i-1]만 있으면 dp[i]를 구할 수 있으므로, dp 배열을 점화식: dp[i] = max(dp[i−2] + nums[i], dp[i−1]) Dynamic Programming 기법에 의해, secondLast와 last를 다음 Iteration에서 재사용할 수 있도록 저장하여 공간 최적화(Space-Optimisation)를 활용할 수 있다. */ -const novacat25_rob = (nums: number[]): number => { +const rob = (nums: number[]): number => { const n = nums.length if (n === 0) return 0 From 17ff8c209efc4b359c9d4a5145e290d29bd29169 Mon Sep 17 00:00:00 2001 From: NovaCat Date: Tue, 10 Nov 2026 17:06:31 +0900 Subject: [PATCH 08/21] Fix: name lint failed(House Robber #264) --- house-robber/{noavacat25.ts => novacat25.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename house-robber/{noavacat25.ts => novacat25.ts} (100%) diff --git a/house-robber/noavacat25.ts b/house-robber/novacat25.ts similarity index 100% rename from house-robber/noavacat25.ts rename to house-robber/novacat25.ts From 6cbe332d91320677cd655a13dcc42fa62da78178 Mon Sep 17 00:00:00 2001 From: NovaCat Date: Tue, 10 Nov 2026 22:43:57 +0900 Subject: [PATCH 09/21] Refactor: delete unnecessary else --- two-sum/novacat25.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/two-sum/novacat25.ts b/two-sum/novacat25.ts index 5b77d90946..074faf4387 100644 --- a/two-sum/novacat25.ts +++ b/two-sum/novacat25.ts @@ -22,9 +22,9 @@ const twoSum = (nums: number[], target: number): number[] => { arr[1] = i break - } else { - map.set(currentNum, i) } + + map.set(currentNum, i) } return arr From 3ee13109301ce4322375e16b80285f0755529bd6 Mon Sep 17 00:00:00 2001 From: NovaCat Date: Wed, 11 Nov 2026 08:58:19 +0900 Subject: [PATCH 10/21] Refactor: delete unnecessary else --- contains-duplicate/novacat25.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contains-duplicate/novacat25.ts b/contains-duplicate/novacat25.ts index 83aaa4800f..45fc5ea556 100644 --- a/contains-duplicate/novacat25.ts +++ b/contains-duplicate/novacat25.ts @@ -16,9 +16,9 @@ const containsDuplicate = (nums: number[]): boolean => { const currentNum = nums[i] if (set.has(currentNum)) { return true - } else { - set.add(currentNum) } + + set.add(currentNum) } return false From c026b76493f5bf7045bc0ebaaad4a9e3a86396fd Mon Sep 17 00:00:00 2001 From: NovaCat Date: Wed, 11 Nov 2026 11:08:46 +0900 Subject: [PATCH 11/21] Add comment: Top-k-frequent-elements --- top-k-frequent-elements/novacat25.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/top-k-frequent-elements/novacat25.ts b/top-k-frequent-elements/novacat25.ts index bac8930c40..0a2b636806 100644 --- a/top-k-frequent-elements/novacat25.ts +++ b/top-k-frequent-elements/novacat25.ts @@ -3,13 +3,14 @@ 시간 복잡도: O(n) 풀이: nums의 length만큼 버킷을 생성하여 Bucket Sort 적용 후 빈도가 높은 순서대로 k개의 숫자를 선택한다. 풀이 History -1차: HashMap + Max Heap을 이용해 k개의 숫자를 선택하는 방식으로 구현하였다.(O(nlogk) 시간 복잡도) 문제 조건 상 시간 복잡도가 O(nlogn) 이하로 나와야 하므로 2차에서 Bucket Sort를 적용하여 O(n) 시간 복잡도로 구현하였다. -2차: 아래의 코드대로 Bucket Sort를 적용하여 k개의 숫자를 선택하는 방식으로 구현하였다.(O(n) 시간 복잡도) +1차: HashMap + Max Heap을 이용해 k개의 숫자를 선택하는 방식으로 구현했다.(O(nlogk) 시간 복잡도) 문제 조건 상 시간 복잡도가 O(nlogn) 이하로 나와야 하므로 2차에서 Bucket Sort를 적용하여 O(n) 시간 복잡도로 구현하였다. +2차: 아래의 코드대로 Bucket Sort를 적용하여 k개의 숫자를 선택하는 방식으로 수정했다.(O(n) 시간 복잡도) +개선점: for 문을 그대로 쓰지 않고, 함수를 만들어서 재사용성을 높이는 방안도 좋을 것으로 생각됨. */ const getBucketSort = (freqArr: number[][], n: number) => { + // freq 값을 그대로 index로 활용하고 싶기 때문에 n+1개의 버킷을 생성한다.(index 0은 사용하지 않음) const buckets: number[][] = Array.from({ length: n + 1 }, () => []) - // Put array elements in different buckets for (let i = 0; i < freqArr.length; i++) { const [num, freq] = freqArr[i] buckets[freq].push(num) From c4cd0dea2e6932f97a0e03f69c0b3eb4f6353064 Mon Sep 17 00:00:00 2001 From: NovaCat Date: Wed, 11 Nov 2026 12:03:52 +0900 Subject: [PATCH 12/21] Fix: Comment(contains-duplicate) / Readability(top-k-frequent-elements) --- contains-duplicate/novacat25.ts | 18 ++++++++++++------ top-k-frequent-elements/novacat25.ts | 3 +-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/contains-duplicate/novacat25.ts b/contains-duplicate/novacat25.ts index 45fc5ea556..3e434ebbba 100644 --- a/contains-duplicate/novacat25.ts +++ b/contains-duplicate/novacat25.ts @@ -1,12 +1,18 @@ -/* +/* 시간 복잡도(Time Complexity): 평균 O(n) - 공간 복잡도(Space Complexity): 평균 O(n) - 풀이 알고리즘: JS의 HashMap / Map 이용 + 공간 복잡도(Space Complexity): O(n) + 풀이 알고리즘: Hash Set (JavaScript Set) 활용 풀이 History - 1트: 예전에 JS의 find() 메서드를 이용해 풀었을 때에는 TLE에 걸리기 일쑤였으니, JS 배열을 정렬(Quick Sort)하고 Binary Search로 일관된 정렬 시간을 확보하자!(X) -> 비효율적인 정렬 코스트로 TLE가 발생하여 틀렸다. - 2트: 이 문제에 정렬(sort) 과정이 필요한가? -> X. 따라서 탐색에 훨씬 유리한 자료구조를 찾아서 푸는 게 낫다고 판단함. - 3트: Map/HashMap을 이용해 Key 기반의 빠른 탐색 및 저장으로 풀자 + 1트: Array.find()를 이용해 중복 여부를 탐색했으나, + 반복적인 배열 탐색으로 인해 시간 초과(TLE) 발생. + + 2트: 배열 정렬 후 Binary Search를 활용하는 방법을 고려했으나, + 정렬에 필요한 추가적인 시간 비용으로 비효율적이라고 판단. + + 3트: Hash Set을 이용한 풀이로 변경. + Set.has()를 통해 기존 데이터의 존재 여부를 평균 O(1)에 확인하고, + Set.add()를 통해 방문한 숫자를 기록. */ const containsDuplicate = (nums: number[]): boolean => { diff --git a/top-k-frequent-elements/novacat25.ts b/top-k-frequent-elements/novacat25.ts index 0a2b636806..f58978ac3f 100644 --- a/top-k-frequent-elements/novacat25.ts +++ b/top-k-frequent-elements/novacat25.ts @@ -11,8 +11,7 @@ const getBucketSort = (freqArr: number[][], n: number) => { // freq 값을 그대로 index로 활용하고 싶기 때문에 n+1개의 버킷을 생성한다.(index 0은 사용하지 않음) const buckets: number[][] = Array.from({ length: n + 1 }, () => []) - for (let i = 0; i < freqArr.length; i++) { - const [num, freq] = freqArr[i] + for (const [num, freq] of freqArr) { buckets[freq].push(num) } From da8b11c0d4af743780bb2c5342f8bb91452088c2 Mon Sep 17 00:00:00 2001 From: NovaCat Date: Wed, 11 Nov 2026 13:13:25 +0900 Subject: [PATCH 13/21] Fix: two-sum --- two-sum/novacat25.ts | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/two-sum/novacat25.ts b/two-sum/novacat25.ts index 074faf4387..e8db0e95c3 100644 --- a/two-sum/novacat25.ts +++ b/two-sum/novacat25.ts @@ -1,31 +1,34 @@ -/* +/* 시간 복잡도(Time Complexity): 평균 O(n) - 공간 복잡도(Space Complexity): 평균 O(n) - 풀이 알고리즘: JS의 HashMap / Map 이용 + 공간 복잡도(Space Complexity): O(n) + 풀이 알고리즘: Hash Map (JavaScript Map) 활용 풀이 History - 1트: 완전 탐색을 이용해 정답은 맞췄으나, Time Complexity가 O(n²) - 2트: HasyMap을 통해 Key - value 플로를 응용하여 O(n)으로 단축 완료 + 1트: 완전 탐색을 이용해 정답은 맞췄으나, + 시간 복잡도가 O(n²)로 비효율적이었음. + + 2트: Hash Map (JavaScript Map)을 활용하여 + 숫자와 인덱스를 Key-Value 형태로 관리. + 보완해야 할 숫자의 존재 여부를 평균 O(1)에 탐색하여 + 전체 시간 복잡도를 O(n)으로 개선. */ const twoSum = (nums: number[], target: number): number[] => { - const map: Map = new Map() - const arr = [0, 0] + const numToIndexMap: Map = new Map() for (let i = 0; i < nums.length; i++) { const currentNum = nums[i] - const anotherPair = target - currentNum + const complement = target - currentNum - if (map.has(anotherPair)) { - // map.has로 값을 가지고 있음이 확정되어 있으므로 non-null assertion을 통해 값 강제 - arr[0] = map.get(anotherPair)! - arr[1] = i + const complementIndex = numToIndexMap.get(complement) - break + if (complementIndex !== undefined) { + return [complementIndex, i] } - map.set(currentNum, i) + numToIndexMap.set(currentNum, i) } - return arr + // Fallback 값으로 임의로 반환하지 않고, 예외를 발생시켜 문제 조건에 맞지 않는 경우를 명시적으로 처리함. + throw new Error("No valid pair found") } From 57efd43650333b722d4387c133fa0233e9d049ad Mon Sep 17 00:00:00 2001 From: NovaCat Date: Wed, 11 Nov 2026 14:16:10 +0900 Subject: [PATCH 14/21] Fix: about comment(Hash OOO -> JavaScript Map / Set) --- contains-duplicate/novacat25.ts | 4 ++-- longest-consecutive-sequence/novacat25.ts | 4 ++-- top-k-frequent-elements/novacat25.ts | 2 +- two-sum/novacat25.ts | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contains-duplicate/novacat25.ts b/contains-duplicate/novacat25.ts index 3e434ebbba..996075e591 100644 --- a/contains-duplicate/novacat25.ts +++ b/contains-duplicate/novacat25.ts @@ -1,7 +1,7 @@ /* 시간 복잡도(Time Complexity): 평균 O(n) 공간 복잡도(Space Complexity): O(n) - 풀이 알고리즘: Hash Set (JavaScript Set) 활용 + 풀이 알고리즘: JavaScript Set 활용 풀이 History 1트: Array.find()를 이용해 중복 여부를 탐색했으나, @@ -10,7 +10,7 @@ 2트: 배열 정렬 후 Binary Search를 활용하는 방법을 고려했으나, 정렬에 필요한 추가적인 시간 비용으로 비효율적이라고 판단. - 3트: Hash Set을 이용한 풀이로 변경. + 3트: Set 자료구조를 이용한 풀이로 변경. Set.has()를 통해 기존 데이터의 존재 여부를 평균 O(1)에 확인하고, Set.add()를 통해 방문한 숫자를 기록. */ diff --git a/longest-consecutive-sequence/novacat25.ts b/longest-consecutive-sequence/novacat25.ts index f2acdc8213..9771349d8c 100644 --- a/longest-consecutive-sequence/novacat25.ts +++ b/longest-consecutive-sequence/novacat25.ts @@ -1,10 +1,10 @@ /* 시간 복잡도(Time Complexity): 평균 O(n) 공간 복잡도(Space Complexity): 평균 O(n) -풀이 알고리즘: JS의 Hash Set 이용 +풀이 알고리즘: JavaScript Set 이용 풀이 History -1트: Hash Set을 떠올렸으나, for(const val of st) 부분에서 불필요한 부분을 탐색하여 TLE가 터졌다. (X) +1트: JavaScript Set을 떠올렸으나, for(const val of st) 부분에서 불필요한 부분을 탐색하여 TLE가 터졌다. (X) 2트: [...st]를 이용해 Set을 Array로 변환 후, for(const val of setArr)로 탐색하여 시간 복잡도를 개선했다. (O(n) 시간 복잡도) 기타: Duplicate identifier 'longestConsecutive' 에러가 발생하는 듯하여 novacatLongestConsecutive라는 이름으로 함수를 변경함. diff --git a/top-k-frequent-elements/novacat25.ts b/top-k-frequent-elements/novacat25.ts index f58978ac3f..e4ce6ac022 100644 --- a/top-k-frequent-elements/novacat25.ts +++ b/top-k-frequent-elements/novacat25.ts @@ -3,7 +3,7 @@ 시간 복잡도: O(n) 풀이: nums의 length만큼 버킷을 생성하여 Bucket Sort 적용 후 빈도가 높은 순서대로 k개의 숫자를 선택한다. 풀이 History -1차: HashMap + Max Heap을 이용해 k개의 숫자를 선택하는 방식으로 구현했다.(O(nlogk) 시간 복잡도) 문제 조건 상 시간 복잡도가 O(nlogn) 이하로 나와야 하므로 2차에서 Bucket Sort를 적용하여 O(n) 시간 복잡도로 구현하였다. +1차: JavaScript Map + Max Heap을 이용해 k개의 숫자를 선택하는 방식으로 구현했다.(O(nlogk) 시간 복잡도) 문제 조건 상 시간 복잡도가 O(nlogn) 이하로 나와야 하므로 2차에서 Bucket Sort를 적용하여 O(n) 시간 복잡도로 구현하였다. 2차: 아래의 코드대로 Bucket Sort를 적용하여 k개의 숫자를 선택하는 방식으로 수정했다.(O(n) 시간 복잡도) 개선점: for 문을 그대로 쓰지 않고, 함수를 만들어서 재사용성을 높이는 방안도 좋을 것으로 생각됨. */ diff --git a/two-sum/novacat25.ts b/two-sum/novacat25.ts index e8db0e95c3..2500b6895e 100644 --- a/two-sum/novacat25.ts +++ b/two-sum/novacat25.ts @@ -1,13 +1,13 @@ /* 시간 복잡도(Time Complexity): 평균 O(n) 공간 복잡도(Space Complexity): O(n) - 풀이 알고리즘: Hash Map (JavaScript Map) 활용 + 풀이 알고리즘: JavaScript Map 활용 풀이 History 1트: 완전 탐색을 이용해 정답은 맞췄으나, 시간 복잡도가 O(n²)로 비효율적이었음. - 2트: Hash Map (JavaScript Map)을 활용하여 + 2트: JavaScript Map을 활용하여 숫자와 인덱스를 Key-Value 형태로 관리. 보완해야 할 숫자의 존재 여부를 평균 O(1)에 탐색하여 전체 시간 복잡도를 O(n)으로 개선. From 87c9e87e0707a0521008df7bef63d43c9b9a2f8a Mon Sep 17 00:00:00 2001 From: NovaCat Date: Thu, 12 Nov 2026 09:25:04 +0900 Subject: [PATCH 15/21] set var name changed: contains-duplicate --- contains-duplicate/novacat25.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contains-duplicate/novacat25.ts b/contains-duplicate/novacat25.ts index 996075e591..ee5b3c708f 100644 --- a/contains-duplicate/novacat25.ts +++ b/contains-duplicate/novacat25.ts @@ -16,15 +16,15 @@ */ const containsDuplicate = (nums: number[]): boolean => { - const set = new Set() + const numSet = new Set() for (let i = 0; i < nums.length; i++) { const currentNum = nums[i] - if (set.has(currentNum)) { + if (numSet.has(currentNum)) { return true } - set.add(currentNum) + numSet.add(currentNum) } return false From 030e522a0bbec7059a295b036b30f0dee2b28b53 Mon Sep 17 00:00:00 2001 From: NovaCat Date: Thu, 12 Nov 2026 15:56:12 +0900 Subject: [PATCH 16/21] numberMap -> freqMap: top-k-frequent-elements --- top-k-frequent-elements/novacat25.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/top-k-frequent-elements/novacat25.ts b/top-k-frequent-elements/novacat25.ts index e4ce6ac022..9445a5ba57 100644 --- a/top-k-frequent-elements/novacat25.ts +++ b/top-k-frequent-elements/novacat25.ts @@ -7,7 +7,7 @@ 2차: 아래의 코드대로 Bucket Sort를 적용하여 k개의 숫자를 선택하는 방식으로 수정했다.(O(n) 시간 복잡도) 개선점: for 문을 그대로 쓰지 않고, 함수를 만들어서 재사용성을 높이는 방안도 좋을 것으로 생각됨. */ -const getBucketSort = (freqArr: number[][], n: number) => { +const getBucketSort = (freqArr: number[][], n: number): number[][] => { // freq 값을 그대로 index로 활용하고 싶기 때문에 n+1개의 버킷을 생성한다.(index 0은 사용하지 않음) const buckets: number[][] = Array.from({ length: n + 1 }, () => []) @@ -22,14 +22,14 @@ const topKFrequent = (nums: number[], k: number): number[] => { const answerArr: number[] = [] const entryArr: number[][] = [] - const numberMap = new Map() + const freqMap = new Map() for (const val of nums) { - const count = (numberMap.get(val) || 0) + 1 - numberMap.set(val, count) + const count = (freqMap.get(val) || 0) + 1 + freqMap.set(val, count) } - for (const entry of numberMap.entries()) { + for (const entry of freqMap.entries()) { entryArr.push(entry) } From 25efbc635c06a0ae9e091e717a11359645406097 Mon Sep 17 00:00:00 2001 From: NovaCat Date: Thu, 12 Nov 2026 16:08:31 +0900 Subject: [PATCH 17/21] st->numberSet: longest-consecutive-sequence --- longest-consecutive-sequence/novacat25.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/longest-consecutive-sequence/novacat25.ts b/longest-consecutive-sequence/novacat25.ts index 9771349d8c..e8b1a36747 100644 --- a/longest-consecutive-sequence/novacat25.ts +++ b/longest-consecutive-sequence/novacat25.ts @@ -11,19 +11,19 @@ */ const novacatLongestConsecutive = (nums: number[]): number => { - const st = new Set() + const numberSet = new Set() let result = 0 for (const val of nums) { - st.add(val) + numberSet.add(val) } - const setArr = [...st] + const setArr = [...numberSet] for (const val of setArr) { - if (!st.has(val - 1)) { + if (!numberSet.has(val - 1)) { let cur = val let cnt = 0 - while (st.has(cur)) { + while (numberSet.has(cur)) { cur++ cnt++ } From bacba450925b34b8b461a1eed5d18941e926c924 Mon Sep 17 00:00:00 2001 From: NovaCat Date: Fri, 13 Nov 2026 09:27:21 +0900 Subject: [PATCH 18/21] Delete unneceesary condition: house-robber --- house-robber/novacat25.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/house-robber/novacat25.ts b/house-robber/novacat25.ts index 21dc25ec78..6d388040bc 100644 --- a/house-robber/novacat25.ts +++ b/house-robber/novacat25.ts @@ -12,7 +12,6 @@ Dynamic Programming 기법에 의해, secondLast와 last를 다음 Iteration에 const rob = (nums: number[]): number => { const n = nums.length - if (n === 0) return 0 if (n === 1) return nums[0] let secondLast = 0 From 73740683a4535c1c26bbc00fcea8d45fa8c8a9fb Mon Sep 17 00:00:00 2001 From: NovaCat Date: Fri, 13 Nov 2026 13:09:52 +0900 Subject: [PATCH 19/21] Make code simpler(Refactor): top-k-frequent-elements --- top-k-frequent-elements/novacat25.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/top-k-frequent-elements/novacat25.ts b/top-k-frequent-elements/novacat25.ts index 9445a5ba57..5994dbab49 100644 --- a/top-k-frequent-elements/novacat25.ts +++ b/top-k-frequent-elements/novacat25.ts @@ -7,7 +7,7 @@ 2차: 아래의 코드대로 Bucket Sort를 적용하여 k개의 숫자를 선택하는 방식으로 수정했다.(O(n) 시간 복잡도) 개선점: for 문을 그대로 쓰지 않고, 함수를 만들어서 재사용성을 높이는 방안도 좋을 것으로 생각됨. */ -const getBucketSort = (freqArr: number[][], n: number): number[][] => { +const getBucketSort = (freqArr: Map, n: number): number[][] => { // freq 값을 그대로 index로 활용하고 싶기 때문에 n+1개의 버킷을 생성한다.(index 0은 사용하지 않음) const buckets: number[][] = Array.from({ length: n + 1 }, () => []) @@ -33,7 +33,7 @@ const topKFrequent = (nums: number[], k: number): number[] => { entryArr.push(entry) } - const bucketArr = getBucketSort(entryArr, nums.length) + const bucketArr = getBucketSort(freqMap, nums.length) for (let i = bucketArr.length - 1; i >= 0; i--) { for (const num of bucketArr[i]) { From 8670adfdf547687c429a95d96508cc22d30aaba4 Mon Sep 17 00:00:00 2001 From: NovaCat Date: Fri, 13 Nov 2026 13:10:41 +0900 Subject: [PATCH 20/21] Hotfix: delete unnecessary var(entryArr): top-k-frequent-elements --- top-k-frequent-elements/novacat25.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/top-k-frequent-elements/novacat25.ts b/top-k-frequent-elements/novacat25.ts index 5994dbab49..19427db186 100644 --- a/top-k-frequent-elements/novacat25.ts +++ b/top-k-frequent-elements/novacat25.ts @@ -20,8 +20,6 @@ const getBucketSort = (freqArr: Map, n: number): number[][] => { const topKFrequent = (nums: number[], k: number): number[] => { const answerArr: number[] = [] - const entryArr: number[][] = [] - const freqMap = new Map() for (const val of nums) { @@ -29,10 +27,6 @@ const topKFrequent = (nums: number[], k: number): number[] => { freqMap.set(val, count) } - for (const entry of freqMap.entries()) { - entryArr.push(entry) - } - const bucketArr = getBucketSort(freqMap, nums.length) for (let i = bucketArr.length - 1; i >= 0; i--) { From bfd682ea2834f4b62555ee4828c062a58d814c10 Mon Sep 17 00:00:00 2001 From: NovaCat Date: Sat, 14 Nov 2026 12:56:30 +0900 Subject: [PATCH 21/21] Refactor: make code simpler(contains-duplicate, longest-consecutive-sequence) --- contains-duplicate/novacat25.ts | 7 +++---- longest-consecutive-sequence/novacat25.ts | 9 ++------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/contains-duplicate/novacat25.ts b/contains-duplicate/novacat25.ts index ee5b3c708f..d28a56571b 100644 --- a/contains-duplicate/novacat25.ts +++ b/contains-duplicate/novacat25.ts @@ -18,13 +18,12 @@ const containsDuplicate = (nums: number[]): boolean => { const numSet = new Set() - for (let i = 0; i < nums.length; i++) { - const currentNum = nums[i] - if (numSet.has(currentNum)) { + for (const num of nums) { + if (numSet.has(num)) { return true } - numSet.add(currentNum) + numSet.add(num) } return false diff --git a/longest-consecutive-sequence/novacat25.ts b/longest-consecutive-sequence/novacat25.ts index e8b1a36747..6b110536a5 100644 --- a/longest-consecutive-sequence/novacat25.ts +++ b/longest-consecutive-sequence/novacat25.ts @@ -11,15 +11,10 @@ */ const novacatLongestConsecutive = (nums: number[]): number => { - const numberSet = new Set() + const numberSet = new Set(nums) let result = 0 - for (const val of nums) { - numberSet.add(val) - } - - const setArr = [...numberSet] - for (const val of setArr) { + for (const val of numberSet) { if (!numberSet.has(val - 1)) { let cur = val let cnt = 0