From 774b615215c4707919ce241360f99040e0916ce4 Mon Sep 17 00:00:00 2001 From: mmyeon Date: Mon, 31 Mar 2025 11:29:02 +0900 Subject: [PATCH 1/6] add solution : 1. Two Sum --- two-sum/mmyeon.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/two-sum/mmyeon.ts b/two-sum/mmyeon.ts index 3b3d8603f..e6172cd12 100644 --- a/two-sum/mmyeon.ts +++ b/two-sum/mmyeon.ts @@ -29,3 +29,30 @@ function twoSum(nums: number[], target: number): number[] { map.set(nums[i], i); } } + +/** + * + * 접근 방법 : + * - 현재 숫자가 확인한 숫자들 목록에 있으면 해당 숫자의 인덱스와 현재 인덱스를 바로 리턴 + * - 숫자들 목록에 없으면 숫자와 인덱스를 map에 저장 + * + * 시간복잡도 : O(n) + * - nums 배열을 1회만 순회하니까 O(n) + * + * 공간복잡도 : O(n) + * - 최악의 경우, nums 배열 크기만큼 map에 저장하니까 O(n) + */ +function twoSum(nums: number[], target: number): number[] { + const seenNumbers = new Map(); + + for (let i = 0; i < nums.length; i++) { + const neededValue = target - nums[i]; + if (seenNumbers.has(neededValue)) { + return [i, seenNumbers.get(neededValue)!]; + } + + seenNumbers.set(nums[i], i); + } + + return []; +} From 9e763c1edbd742388dabcb9a561285b6fa9b6d25 Mon Sep 17 00:00:00 2001 From: mmyeon Date: Tue, 1 Apr 2025 11:02:05 +0900 Subject: [PATCH 2/6] add solution : 217. Contains Duplicate --- contains-duplicate/mmyeon.js | 22 ---------------------- contains-duplicate/mmyeon.ts | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 22 deletions(-) delete mode 100644 contains-duplicate/mmyeon.js create mode 100644 contains-duplicate/mmyeon.ts diff --git a/contains-duplicate/mmyeon.js b/contains-duplicate/mmyeon.js deleted file mode 100644 index 9af2a45e3..000000000 --- a/contains-duplicate/mmyeon.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @param {number[]} nums - * @return {boolean} - */ - -/** - * - * 접근 방법 - * - Set 객체 사용해서 숫자 중복 제거하기 - * - 원본 배열과 길이 비교하기 - * - * 시간복잡도 : - * - 배열 순회해서 요소 Set에 삽입 : O(n) - * - Set의 사이즈 크기 비교 : O(1) - * - * 공간복잡도 : - * - Set에 유니크한 숫자 저장 : O(n) - */ - -var containsDuplicate = function (nums) { - return new Set(nums).size !== nums.length; -}; diff --git a/contains-duplicate/mmyeon.ts b/contains-duplicate/mmyeon.ts new file mode 100644 index 000000000..11fe18070 --- /dev/null +++ b/contains-duplicate/mmyeon.ts @@ -0,0 +1,14 @@ +/** + * + * 접근 방법 : + * - set 자료구조에 nums 값 담아서 set의 크기와 배열의 길이를 비교하기 + * + * 시간복잡도 : O(n) + * - nums 배열을 순회해서 set에 저장하니까 O(n) + * + * 공간복잡도 : O(n) + * - nums 배열의 길이만큼 set에 담으니까 O(n) + */ +function containsDuplicate(nums: number[]): boolean { + return nums.length !== new Set([...nums]).size; +} From 90b6bcea377aa7653a8fe8335d411007047dd6a2 Mon Sep 17 00:00:00 2001 From: mmyeon Date: Tue, 1 Apr 2025 14:22:30 +0900 Subject: [PATCH 3/6] add solution : 347. Top K Frequent Elements --- top-k-frequent-elements/mmyeon.js | 33 --------------------------- top-k-frequent-elements/mmyeon.ts | 38 +++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 33 deletions(-) delete mode 100644 top-k-frequent-elements/mmyeon.js create mode 100644 top-k-frequent-elements/mmyeon.ts diff --git a/top-k-frequent-elements/mmyeon.js b/top-k-frequent-elements/mmyeon.js deleted file mode 100644 index 7fdce1cb1..000000000 --- a/top-k-frequent-elements/mmyeon.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * 접근 방법 : - * - 숫자 바열을 전체 순회하면서 빈도수를 객체에 저장 - * - 객체 값을 내림차순으로 정렬한 뒤, 원하는 항목만큼 자르고 숫자로 변환한 뒤 리턴하기 - * - * 시간복잡도 : O(nlogn) - * - 숫자 배열 길이 = n , 가져올 항목 개수 = k - * - 객체에 숫자와 빈도수 저장하기 위해서 모든 숫자 순회 : O(n) - * - 객체 키값을 내림차순으로 정렬 : O(nlogn) - * - slice, map : O(k) - * - * 공간복잡도 : - * - 숫자 배열의 길이만큼 객체에 저장하니까 O(n) - */ - -/** - * @param {number[]} nums - * @param {number} k - * @return {number[]} - */ - -var topKFrequent = function (nums, k) { - const obj = {}; - - for (const num of nums) { - obj[num] = (obj[num] ?? 0) + 1; - } - - return Object.entries(obj) - .sort((a, b) => b[1] - a[1]) - .slice(0, k) - .map((item) => Number(item[0])); -}; diff --git a/top-k-frequent-elements/mmyeon.ts b/top-k-frequent-elements/mmyeon.ts new file mode 100644 index 000000000..346e96e54 --- /dev/null +++ b/top-k-frequent-elements/mmyeon.ts @@ -0,0 +1,38 @@ +/** + * + * 접근 방법 : + * - 정렬 사용하지 않고 o(n)을 풀기 위해서 숫자 빈도수를 배열 인덱스로 저장 + * - 숫자 빈도스를 맵에 저장 + * - 맵을 순회하면서, 빈도수를 배열에 저장 (동일 반도수 처리하기 위해서 2차원 배열 사용) + * - 배열을 역순으로 순회하면서 빈도수 기반의 값을 결과 배열에 저장 + * - 결과 배열을 k개만큼 잘라서 리턴 + * + * 시간복잡도 : O(n) + * - nums 배열 1회 순회하면서 맵에 저장하니까 O(n) + * + * 공간복잡도 : O(n) + * - nums 배열 길이만큼 맵과 2차원 배열에 정리하니까 O(n) + */ +function topKFrequent(nums: number[], k: number): number[] { + const numMap = new Map(); + + for (const num of nums) { + numMap.set(num, (numMap.get(num) ?? 0) + 1); + } + + const storedArr: number[][] = Array(nums.length + 1) + .fill(null) + .map(() => []); + + for (const [num, frequency] of numMap) { + storedArr[frequency].push(num); + } + + const result: number[] = []; + + for (let i = storedArr.length - 1; i >= 0; i--) { + if (storedArr[i].length > 0) result.push(...storedArr[i]); + } + + return result.slice(0, k); +} From cb600d66ac5bb146fba86234ba5ffea3c2e3c01a Mon Sep 17 00:00:00 2001 From: mmyeon Date: Wed, 2 Apr 2025 13:23:29 +0900 Subject: [PATCH 4/6] add solution : 128. Longest Consecutive Sequence --- longest-common-subsequence/mmyeon.js | 46 -------------------------- longest-consecutive-sequence/mmyeon.ts | 33 ++++++++++++++++++ 2 files changed, 33 insertions(+), 46 deletions(-) delete mode 100644 longest-common-subsequence/mmyeon.js create mode 100644 longest-consecutive-sequence/mmyeon.ts diff --git a/longest-common-subsequence/mmyeon.js b/longest-common-subsequence/mmyeon.js deleted file mode 100644 index bc9dfcc47..000000000 --- a/longest-common-subsequence/mmyeon.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * - * 접근 방법 : - * - 중복 숫자 제거한 뒤, 숫자 순회하면서 연속 숫자의 시작 지점인지 체크 - * - 더 작은 숫자가 없으면 현재 숫자가 연속 숫자의 시작 지점이기 때문에, 연속된 다음 큰 숫자가 존재하는지 체크 - * - 있으면 count 증가시키고, 그 다음 숫자 있는지 반복해서 체크 - * - 연속 숫자가 존재하지 않을 때까지 순회하기 - * - count가 maxCount보다 큰 경우 maxCount값을 count 값으로 업데이트 - * - * 시간복잡도 : - * - 숫자 배열 길이를 모두 순회하니까 O(n) - * - * 공간복잡도 : - * - Set을 사용해서 숫자 중복 제거하고 저장하니까 O(n) - */ - -/** - * @param {number[]} nums - * @return {number} - */ -var longestConsecutive = function (nums) { - // 배열 비어있는 경우 처리 - if (nums.length === 0) return 0; - - const uniqueNums = new Set(nums); - let maxCount = 1; - - for (const num of uniqueNums) { - // 연속된 숫자의 시작 지점인지 체크(더 작은 숫자가 존재하지 않아야 함) - if (!uniqueNums.has(num - 1)) { - let next = num + 1; - let count = 1; - - // 연속 숫자가 더 존재하는지 체크 - while (uniqueNums.has(next)) { - next++; - count++; - } - - // 기존 maxCount보다 크면, count 값으로 업데이트하기 - if (maxCount < count) maxCount = count; - } - } - - return maxCount; -}; diff --git a/longest-consecutive-sequence/mmyeon.ts b/longest-consecutive-sequence/mmyeon.ts new file mode 100644 index 000000000..8ddd40ffa --- /dev/null +++ b/longest-consecutive-sequence/mmyeon.ts @@ -0,0 +1,33 @@ +/** + * + * 접근 방법 : + * - 중복 숫자 제거하고 빠르게 조회하기 위해서 Set 사용 + * - 연속된 숫자의 시작점(현재 숫자보다 작은 숫자가 없는 경우)를 찾아서 연속된 길이 카운트 + * - 최대 길이 갱신 + * + * 시간복잡도 : O(n) + * - Set 생성, 숫자 탐색 모두 O(n) + * + * 공간복잡도 : O(n) + * - 최악의 경우, nums 배열 크기만큼 set에 저장하니까 O(n) + */ +function longestConsecutive(nums: number[]): number { + const numSet = new Set(nums); + let longestLength = 0; + + for (const num of numSet) { + if (!numSet.has(num - 1)) { + let currentLength = 1; + let currentNum = num + 1; + + while (numSet.has(currentNum)) { + currentLength++; + currentNum++; + } + + longestLength = Math.max(longestLength, currentLength); + } + } + + return longestLength; +} From 5afc675b758a7482a3c35019447ed06907e17a4d Mon Sep 17 00:00:00 2001 From: mmyeon Date: Fri, 4 Apr 2025 09:39:06 +0900 Subject: [PATCH 5/6] add solution : 198. House Robber --- house-robber/mmyeon.js | 34 ---------------------------- house-robber/mmyeon.ts | 50 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 34 deletions(-) delete mode 100644 house-robber/mmyeon.js create mode 100644 house-robber/mmyeon.ts diff --git a/house-robber/mmyeon.js b/house-robber/mmyeon.js deleted file mode 100644 index 0e4aff237..000000000 --- a/house-robber/mmyeon.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * - * 접근 방법 : dp 사용 - * - 배열 길이가 1개 일때는 첫 번쨰 값 리턴하고, 2개면 더 큰 수를 리턴한다. - * - 3개 부터는 바로 옆집 값에 현재집 값을 더한 값과 옆옆집의 값을 비교해서 큰 값을 계산한다. - * - 다음 집 값에 현재까지의 값 활용하기 위해서, 바로 옆집, 옆옆집 값을 업데이트해준다. - * - 현재 값이 저장된 옆집값을 리턴한다. - * - * 시간복잡도 : - * - 주어진 숫자 배열 길이만큼 1회 순회하니까 O(n) - * - * 공간복잡도 : - * - 옆집과 옆옆집 값을 2개의 변수에 저장해야하니까 O(1) - * - */ -/** - * @param {number[]} nums - * @return {number} - */ -var rob = function (nums) { - if (nums.length === 1) return nums[0]; - if (nums.length === 2) return Math.max(nums[0], nums[1]); - - let prevPrevHouse = nums[0]; - let prevHouse = Math.max(nums[0], nums[1]); - - for (let i = 2; i < nums.length; i++) { - const current = Math.max(prevHouse, prevPrevHouse + nums[i]); - prevPrevHouse = prevHouse; - prevHouse = current; - } - - return prevHouse; -}; diff --git a/house-robber/mmyeon.ts b/house-robber/mmyeon.ts new file mode 100644 index 000000000..55c4935a9 --- /dev/null +++ b/house-robber/mmyeon.ts @@ -0,0 +1,50 @@ +/** + * + * 접근 방법 : + * - 최적의 해를 구하기 위해서 dp 사용 + * - 현재 인덱스까지 훔칠 수 있는 가장 큰 값을 dp에 저장 + * + * 시간복잡도 : O(n) + * - nums 배열을 1회만 순회하니까 O(n) + * + * 공간복잡도 : O(n) + * - nums 배열 크기만큼 dp 배열에 저장 + */ +function rob(nums: number[]): number { + 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]; +} + +/** + * + * 접근 방법 : 공간 복잡도 O(1)로 최적화 + * - 이전 두 값만 저장하는 방식으로 개선 + * + * 시간복잡도 : O(n) + * + * 공간복잡도 : O(1) + * - 고정된 변수만 사용 + */ +function rob(nums: number[]): number { + if (nums.length === 1) return nums[0]; + if (nums.length === 2) return Math.max(nums[0], nums[1]); + + let prev2 = nums[0]; + let prev1 = Math.max(nums[0], nums[1]); + + for (let i = 2; i < nums.length; i++) { + const current = Math.max(prev1, prev2 + nums[i]); + prev2 = prev1; + prev1 = current; + } + + return prev1; +} From 4da73d7c83e50071e88e1bd747ecf23f58c259eb Mon Sep 17 00:00:00 2001 From: mmyeon Date: Fri, 4 Apr 2025 23:17:43 +0900 Subject: [PATCH 6/6] apply feedback --- contains-duplicate/mmyeon.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contains-duplicate/mmyeon.ts b/contains-duplicate/mmyeon.ts index 11fe18070..8c5e040d8 100644 --- a/contains-duplicate/mmyeon.ts +++ b/contains-duplicate/mmyeon.ts @@ -10,5 +10,5 @@ * - nums 배열의 길이만큼 set에 담으니까 O(n) */ function containsDuplicate(nums: number[]): boolean { - return nums.length !== new Set([...nums]).size; + return nums.length !== new Set(nums).size; }