From 2a04b9d03bcf404dc9b54bda7c0599581e282356 Mon Sep 17 00:00:00 2001 From: SuKyoung Date: Tue, 1 Apr 2025 11:44:00 +0900 Subject: [PATCH 1/9] add: #219 two sum --- two-sum/suKyoung.ts | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 two-sum/suKyoung.ts diff --git a/two-sum/suKyoung.ts b/two-sum/suKyoung.ts new file mode 100644 index 000000000..bca2ef9fb --- /dev/null +++ b/two-sum/suKyoung.ts @@ -0,0 +1,45 @@ +// 1번째 풀이 (brute force) +function twoSum1(nums: number[], target: number): number[] { + for(let i = 0; i < nums.length; i++) { + for (let j = 1; j < nums.length; j++) { + const a = nums[i]; + const b = nums[j]; + + if (a + b === target && i !== j) { + return [i, j]; + } + } + } + return []; +}; + +// 2번째 풀이 (indexOf) +function twoSum2(nums: number[], target: number): number[] { + for (let i = 0; i < nums.length; i++) { + const j = target - nums[i]; + const index = nums.indexOf(j); + + if (nums.includes(j) && i !== index) { + return [i, index]; + } + } + return []; +}; + +// 3번째 풀이 (HashMap) +function twoSum(nums: number[], target: number): number[] { + const map: Record = {}; + + for (let i = 0; i < nums.length; i++) { + const complement = target - nums[i]; + + if (complement in map) { + const j = map[complement]; + return [i, j]; + } else { + map[nums[i]] = i; + } + } + + return []; +}; \ No newline at end of file From 8ff78df165b05065bc440edd64667083e3014767 Mon Sep 17 00:00:00 2001 From: SuKyoung Date: Tue, 1 Apr 2025 15:27:05 +0900 Subject: [PATCH 2/9] add: #217 contains duplicate --- contains-duplicate/suKyoung.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 contains-duplicate/suKyoung.ts diff --git a/contains-duplicate/suKyoung.ts b/contains-duplicate/suKyoung.ts new file mode 100644 index 000000000..c2da20cab --- /dev/null +++ b/contains-duplicate/suKyoung.ts @@ -0,0 +1,26 @@ +// 1번째 풀이 (hashMap) +function containsDuplicate1(nums: number[]): boolean { + const seen: Record = {}; + + const isDuplicate = nums.some((num) => { + if (seen[num]) return true; + seen[num] = true; + return false; + }); + + return isDuplicate; +} + +// 2번째 풀이(Set) +function containsDuplicate2(nums: number[]): boolean { + const set = new Set(); + + for (const num of nums) { + if (set.has(num)) { + return true; + } + set.add(num); + } + + return false; +} From 0b725bbb064130a3e8ecf07d8b8d218d7d4d3ea1 Mon Sep 17 00:00:00 2001 From: SuKyoung Date: Wed, 2 Apr 2025 20:30:56 +0900 Subject: [PATCH 3/9] add: #347 top k frequent elements --- top-k-frequent-elements/suKyoung.ts | 105 ++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 top-k-frequent-elements/suKyoung.ts diff --git a/top-k-frequent-elements/suKyoung.ts b/top-k-frequent-elements/suKyoung.ts new file mode 100644 index 000000000..46288991e --- /dev/null +++ b/top-k-frequent-elements/suKyoung.ts @@ -0,0 +1,105 @@ +// 1번풀이 (brute force) +type FrequencyMap = Record; + +function topKFrequentCountDown(nums: number[], k: number): number[] { + const freqMap = buildFrequencyMap1(nums); + return pickTopKDescending(freqMap, k); +} + +function buildFrequencyMap1(nums: number[]): FrequencyMap { + const map: FrequencyMap = {}; + for (const num of nums) { + map[num] = (map[num] || 0) + 1; + } + return map; +} + +function pickTopKDescending(freqMap: FrequencyMap, k: number): number[] { + const result: number[] = []; + const entries = Object.entries(freqMap).map(([key, value]) => [ + Number(key), + value, + ]); + let currentFrequent = Math.max(...entries.map(([_, freq]) => freq)); + + while (result.length < k && currentFrequent > 0) { + for (const [num, freq] of entries) { + if (freq === currentFrequent) { + result.push(num); + if (result.length === k) break; + } + } + currentFrequent--; + } + + return result; +} + + +// 2번풀이(Bucket Sort) +function topKFrequent(nums: number[], k: number): number[] { + const frequencyMap = buildFrequencyMap2(nums); + const frequencyBuckets = buildFrequencyBuckets(nums.length, frequencyMap); + + return collectTopKFrequent(frequencyBuckets, k); + } + + function buildFrequencyMap2(nums: number[]): FrequencyMap { + const freqMap: FrequencyMap = {}; + for (const num of nums) { + freqMap[num] = (freqMap[num] || 0) + 1; + } + return freqMap; + } + + function buildFrequencyBuckets( + size: number, + freqMap: FrequencyMap + ): number[][] { + const buckets: number[][] = Array(size + 1).fill(null).map(() => []); + + for (const [numStr, frequent] of Object.entries(freqMap)) { + const num = Number(numStr); + buckets[frequent].push(num); + } + + return buckets; + } + + function collectTopKFrequent(buckets: number[][], k: number): number[] { + const result: number[] = []; + + for (let i = buckets.length - 1; i >= 0 && result.length < k; i--) { + for (const num of buckets[i]) { + result.push(num); + if (result.length === k) break; + } + } + + return result; + } + + +// 3번풀이 (MinHeap) +function topKFrequentHeap(nums: number[], k: number): number[] { + const freqMap: Record = {}; + + for (const num of nums) { + freqMap[num] = (freqMap[num] || 0) + 1; + } + + const heap: [number, number][] = []; + for (const [numStr, frequent] of Object.entries(freqMap)) { + const num = Number(numStr); + + heap.push([num, frequent]); + heap.sort((a, b) => a[1] - b[1]); + + if (heap.length > k) { + heap.shift(); + } + } + + return heap.map(([num]) => num); + } + \ No newline at end of file From 21d1e5ecd2c0d68f588da38efceb5444388cf9e9 Mon Sep 17 00:00:00 2001 From: SuKyoung Date: Thu, 3 Apr 2025 10:21:53 +0900 Subject: [PATCH 4/9] add: #240 Longest Consecutive Sequence --- longest-consecutive-sequence/suKyoung.ts | 46 ++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 longest-consecutive-sequence/suKyoung.ts diff --git a/longest-consecutive-sequence/suKyoung.ts b/longest-consecutive-sequence/suKyoung.ts new file mode 100644 index 000000000..71d8c5bfb --- /dev/null +++ b/longest-consecutive-sequence/suKyoung.ts @@ -0,0 +1,46 @@ +// 1번풀이 +function longestConsecutive2(nums: number[]): number { + if (nums.length === 0) return 0; + + const copiedNums = [...new Set(nums)].sort((a, b) => a - b); + + let max = 1; // 지금까지 나왔던 가장 긴 연속 수열의 길이 + let count = 1; // 현재 연속 수열의 길이 + + for (let i = 1; i < copiedNums.length; i++) { + const prev = copiedNums[i - 1]; + const current = copiedNums[i]; + + if (current === prev + 1) { + count++; + max = Math.max(max, count); + } else { + count = 1; + } + } + + return max; +} + +// 2번풀이 (hashSet) +function longestConsecutive(nums: number[]): number { + const numSet = new Set(nums); + let max = 0; + + for (const num of numSet) { + // 수열의 시작점인 경우만 탐색 + if (!numSet.has(num - 1)) { + let current = num; + let count = 1; + + while (numSet.has(current + 1)) { + current++; + count++; + } + + max = Math.max(max, count); + } + } + + return max; +} From 9a6d07f135a983c77e2729322eca1eac711a2da3 Mon Sep 17 00:00:00 2001 From: SuKyoung Date: Sat, 5 Apr 2025 12:49:02 +0900 Subject: [PATCH 5/9] add: #264 house robber --- house-robber/suKyoung.ts | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 house-robber/suKyoung.ts diff --git a/house-robber/suKyoung.ts b/house-robber/suKyoung.ts new file mode 100644 index 000000000..7676353ee --- /dev/null +++ b/house-robber/suKyoung.ts @@ -0,0 +1,32 @@ +// 1번풀이 (brute force) +// function rob(nums: number[]): number { +// const n = nums.length; +// if (n === 1) return nums[0]; +// if (n === 2) return Math.max(nums[0], nums[1]); + +// const dp: number[] = []; +// dp[0] = nums[0]; +// dp[1] = Math.max(nums[0], nums[1]); + +// for (let i = 2; i < n; i++) { +// dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]); +// } + +// return dp[n - 1]; +// } + +// 2번풀이 (dp) +function rob(nums: number[]): number { + if (nums.length <= 1) return nums[0] ?? 0; + + const dp: number[] = []; + dp[0] = nums[0]; + dp[1] = Math.max(nums[0], nums[1]); + + for (let i = 2; i < nums.length; i++) { + dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]); + } + + return dp[nums.length - 1]; + } + \ No newline at end of file From 3d274dd78c751f679ae333e617e6d5b3a053e7bc Mon Sep 17 00:00:00 2001 From: SuKyoung Date: Sat, 5 Apr 2025 20:09:12 +0900 Subject: [PATCH 6/9] fix: #347 shift() -> pop() --- top-k-frequent-elements/suKyoung.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/top-k-frequent-elements/suKyoung.ts b/top-k-frequent-elements/suKyoung.ts index 46288991e..3d19e7c17 100644 --- a/top-k-frequent-elements/suKyoung.ts +++ b/top-k-frequent-elements/suKyoung.ts @@ -93,10 +93,10 @@ function topKFrequentHeap(nums: number[], k: number): number[] { const num = Number(numStr); heap.push([num, frequent]); - heap.sort((a, b) => a[1] - b[1]); + heap.sort((a, b) => b[1] - a[1]); if (heap.length > k) { - heap.shift(); + heap.pop(); } } From c2deba0bd3229a9a077cb1292c67e2196adb81a8 Mon Sep 17 00:00:00 2001 From: SuKyoung Date: Sat, 5 Apr 2025 20:10:32 +0900 Subject: [PATCH 7/9] =?UTF-8?q?fix:=20#219=20=EC=A4=91=EB=B3=B5=20loop?= =?UTF-8?q?=EB=AC=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- two-sum/suKyoung.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/two-sum/suKyoung.ts b/two-sum/suKyoung.ts index bca2ef9fb..9e68f241d 100644 --- a/two-sum/suKyoung.ts +++ b/two-sum/suKyoung.ts @@ -16,15 +16,15 @@ function twoSum1(nums: number[], target: number): number[] { // 2번째 풀이 (indexOf) function twoSum2(nums: number[], target: number): number[] { for (let i = 0; i < nums.length; i++) { - const j = target - nums[i]; - const index = nums.indexOf(j); - - if (nums.includes(j) && i !== index) { - return [i, index]; - } + const j = target - nums[i]; + const index = nums.indexOf(j); + + if (index !== -1 && i !== index) { + return [i, index]; + } } return []; -}; + }; // 3번째 풀이 (HashMap) function twoSum(nums: number[], target: number): number[] { @@ -42,4 +42,4 @@ function twoSum(nums: number[], target: number): number[] { } return []; -}; \ No newline at end of file +}; From 7c4c547118247da0c5dc0f1cd4d710c29d034f09 Mon Sep 17 00:00:00 2001 From: SuKyoung Date: Sat, 5 Apr 2025 20:30:43 +0900 Subject: [PATCH 8/9] =?UTF-8?q?fix:=20lint=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contains-duplicate/suKyoung.ts | 4 +- house-robber/suKyoung.ts | 23 +++-- longest-consecutive-sequence/suKyoung.ts | 4 +- top-k-frequent-elements/suKyoung.ts | 117 +++++++++++------------ two-sum/suKyoung.ts | 60 ++++++------ 5 files changed, 103 insertions(+), 105 deletions(-) diff --git a/contains-duplicate/suKyoung.ts b/contains-duplicate/suKyoung.ts index c2da20cab..4f8e30c2e 100644 --- a/contains-duplicate/suKyoung.ts +++ b/contains-duplicate/suKyoung.ts @@ -9,7 +9,7 @@ function containsDuplicate1(nums: number[]): boolean { }); return isDuplicate; -} +}; // 2번째 풀이(Set) function containsDuplicate2(nums: number[]): boolean { @@ -23,4 +23,4 @@ function containsDuplicate2(nums: number[]): boolean { } return false; -} +}; diff --git a/house-robber/suKyoung.ts b/house-robber/suKyoung.ts index 7676353ee..f4321d245 100644 --- a/house-robber/suKyoung.ts +++ b/house-robber/suKyoung.ts @@ -17,16 +17,15 @@ // 2번풀이 (dp) function rob(nums: number[]): number { - if (nums.length <= 1) return nums[0] ?? 0; - - const dp: number[] = []; - dp[0] = nums[0]; - dp[1] = Math.max(nums[0], nums[1]); - - for (let i = 2; i < nums.length; i++) { - dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]); - } - - return dp[nums.length - 1]; + if (nums.length <= 1) return nums[0] ?? 0; + + const dp: number[] = []; + dp[0] = nums[0]; + dp[1] = Math.max(nums[0], nums[1]); + + for (let i = 2; i < nums.length; i++) { + dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]); } - \ No newline at end of file + + return dp[nums.length - 1]; +}; diff --git a/longest-consecutive-sequence/suKyoung.ts b/longest-consecutive-sequence/suKyoung.ts index 71d8c5bfb..a182e57b9 100644 --- a/longest-consecutive-sequence/suKyoung.ts +++ b/longest-consecutive-sequence/suKyoung.ts @@ -20,7 +20,7 @@ function longestConsecutive2(nums: number[]): number { } return max; -} +}; // 2번풀이 (hashSet) function longestConsecutive(nums: number[]): number { @@ -43,4 +43,4 @@ function longestConsecutive(nums: number[]): number { } return max; -} +}; diff --git a/top-k-frequent-elements/suKyoung.ts b/top-k-frequent-elements/suKyoung.ts index 3d19e7c17..5dc919941 100644 --- a/top-k-frequent-elements/suKyoung.ts +++ b/top-k-frequent-elements/suKyoung.ts @@ -4,7 +4,7 @@ type FrequencyMap = Record; function topKFrequentCountDown(nums: number[], k: number): number[] { const freqMap = buildFrequencyMap1(nums); return pickTopKDescending(freqMap, k); -} +}; function buildFrequencyMap1(nums: number[]): FrequencyMap { const map: FrequencyMap = {}; @@ -12,7 +12,7 @@ function buildFrequencyMap1(nums: number[]): FrequencyMap { map[num] = (map[num] || 0) + 1; } return map; -} +}; function pickTopKDescending(freqMap: FrequencyMap, k: number): number[] { const result: number[] = []; @@ -33,73 +33,72 @@ function pickTopKDescending(freqMap: FrequencyMap, k: number): number[] { } return result; -} - +}; // 2번풀이(Bucket Sort) function topKFrequent(nums: number[], k: number): number[] { - const frequencyMap = buildFrequencyMap2(nums); - const frequencyBuckets = buildFrequencyBuckets(nums.length, frequencyMap); + const frequencyMap = buildFrequencyMap2(nums); + const frequencyBuckets = buildFrequencyBuckets(nums.length, frequencyMap); - return collectTopKFrequent(frequencyBuckets, k); - } - - function buildFrequencyMap2(nums: number[]): FrequencyMap { - const freqMap: FrequencyMap = {}; - for (const num of nums) { - freqMap[num] = (freqMap[num] || 0) + 1; - } - return freqMap; + return collectTopKFrequent(frequencyBuckets, k); +}; + +function buildFrequencyMap2(nums: number[]): FrequencyMap { + const freqMap: FrequencyMap = {}; + for (const num of nums) { + freqMap[num] = (freqMap[num] || 0) + 1; } - - function buildFrequencyBuckets( - size: number, - freqMap: FrequencyMap - ): number[][] { - const buckets: number[][] = Array(size + 1).fill(null).map(() => []); - - for (const [numStr, frequent] of Object.entries(freqMap)) { - const num = Number(numStr); - buckets[frequent].push(num); - } - - return buckets; + return freqMap; +}; + +function buildFrequencyBuckets( + size: number, + freqMap: FrequencyMap +): number[][] { + const buckets: number[][] = Array(size + 1) + .fill(null) + .map(() => []); + + for (const [numStr, frequent] of Object.entries(freqMap)) { + const num = Number(numStr); + buckets[frequent].push(num); } - - function collectTopKFrequent(buckets: number[][], k: number): number[] { - const result: number[] = []; - - for (let i = buckets.length - 1; i >= 0 && result.length < k; i--) { - for (const num of buckets[i]) { - result.push(num); - if (result.length === k) break; - } + + return buckets; +}; + +function collectTopKFrequent(buckets: number[][], k: number): number[] { + const result: number[] = []; + + for (let i = buckets.length - 1; i >= 0 && result.length < k; i--) { + for (const num of buckets[i]) { + result.push(num); + if (result.length === k) break; } - - return result; } - + + return result; +}; // 3번풀이 (MinHeap) function topKFrequentHeap(nums: number[], k: number): number[] { - const freqMap: Record = {}; - - for (const num of nums) { - freqMap[num] = (freqMap[num] || 0) + 1; - } - - const heap: [number, number][] = []; - for (const [numStr, frequent] of Object.entries(freqMap)) { - const num = Number(numStr); - - heap.push([num, frequent]); - heap.sort((a, b) => b[1] - a[1]); - - if (heap.length > k) { - heap.pop(); - } + const freqMap: Record = {}; + + for (const num of nums) { + freqMap[num] = (freqMap[num] || 0) + 1; + } + + const heap: [number, number][] = []; + for (const [numStr, frequent] of Object.entries(freqMap)) { + const num = Number(numStr); + + heap.push([num, frequent]); + heap.sort((a, b) => b[1] - a[1]); + + if (heap.length > k) { + heap.pop(); } - - return heap.map(([num]) => num); } - \ No newline at end of file + + return heap.map(([num]) => num); +}; diff --git a/two-sum/suKyoung.ts b/two-sum/suKyoung.ts index 9e68f241d..2644f3de8 100644 --- a/two-sum/suKyoung.ts +++ b/two-sum/suKyoung.ts @@ -1,45 +1,45 @@ // 1번째 풀이 (brute force) function twoSum1(nums: number[], target: number): number[] { - for(let i = 0; i < nums.length; i++) { - for (let j = 1; j < nums.length; j++) { - const a = nums[i]; - const b = nums[j]; + for (let i = 0; i < nums.length; i++) { + for (let j = 1; j < nums.length; j++) { + const a = nums[i]; + const b = nums[j]; - if (a + b === target && i !== j) { - return [i, j]; - } - } + if (a + b === target && i !== j) { + return [i, j]; + } } - return []; + } + return []; }; // 2번째 풀이 (indexOf) function twoSum2(nums: number[], target: number): number[] { - for (let i = 0; i < nums.length; i++) { - const j = target - nums[i]; - const index = nums.indexOf(j); - - if (index !== -1 && i !== index) { - return [i, index]; - } + for (let i = 0; i < nums.length; i++) { + const j = target - nums[i]; + const index = nums.indexOf(j); + + if (index !== -1 && i !== index) { + return [i, index]; } - return []; - }; + } + return []; +}; // 3번째 풀이 (HashMap) -function twoSum(nums: number[], target: number): number[] { - const map: Record = {}; - - for (let i = 0; i < nums.length; i++) { - const complement = target - nums[i]; +function twoSum3(nums: number[], target: number): number[] { + const map: Record = {}; + + for (let i = 0; i < nums.length; i++) { + const complement = target - nums[i]; - if (complement in map) { - const j = map[complement]; - return [i, j]; - } else { - map[nums[i]] = i; - } + if (complement in map) { + const j = map[complement]; + return [i, j]; + } else { + map[nums[i]] = i; } + } - return []; + return []; }; From c32206afb8c19f9851bbd034332ecb50ecb7e068 Mon Sep 17 00:00:00 2001 From: SuKyoung Date: Sat, 5 Apr 2025 20:33:43 +0900 Subject: [PATCH 9/9] =?UTF-8?q?fix:=20yaml=20=EA=B7=9C=EC=B9=99=EC=97=90?= =?UTF-8?q?=20=EB=A7=9E=EA=B2=8C=20=ED=8C=8C=EC=9D=BC=EB=AA=85=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contains-duplicate/{suKyoung.ts => sukyoungshin.ts} | 0 house-robber/{suKyoung.ts => sukyoungshin.ts} | 0 longest-consecutive-sequence/{suKyoung.ts => sukyoungshin.ts} | 0 top-k-frequent-elements/{suKyoung.ts => sukyoungshin.ts} | 0 two-sum/{suKyoung.ts => sukyoungshin.ts} | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename contains-duplicate/{suKyoung.ts => sukyoungshin.ts} (100%) rename house-robber/{suKyoung.ts => sukyoungshin.ts} (100%) rename longest-consecutive-sequence/{suKyoung.ts => sukyoungshin.ts} (100%) rename top-k-frequent-elements/{suKyoung.ts => sukyoungshin.ts} (100%) rename two-sum/{suKyoung.ts => sukyoungshin.ts} (100%) diff --git a/contains-duplicate/suKyoung.ts b/contains-duplicate/sukyoungshin.ts similarity index 100% rename from contains-duplicate/suKyoung.ts rename to contains-duplicate/sukyoungshin.ts diff --git a/house-robber/suKyoung.ts b/house-robber/sukyoungshin.ts similarity index 100% rename from house-robber/suKyoung.ts rename to house-robber/sukyoungshin.ts diff --git a/longest-consecutive-sequence/suKyoung.ts b/longest-consecutive-sequence/sukyoungshin.ts similarity index 100% rename from longest-consecutive-sequence/suKyoung.ts rename to longest-consecutive-sequence/sukyoungshin.ts diff --git a/top-k-frequent-elements/suKyoung.ts b/top-k-frequent-elements/sukyoungshin.ts similarity index 100% rename from top-k-frequent-elements/suKyoung.ts rename to top-k-frequent-elements/sukyoungshin.ts diff --git a/two-sum/suKyoung.ts b/two-sum/sukyoungshin.ts similarity index 100% rename from two-sum/suKyoung.ts rename to two-sum/sukyoungshin.ts