diff --git a/contains-duplicate/sadie100.ts b/contains-duplicate/sadie100.ts new file mode 100644 index 000000000..74490de1f --- /dev/null +++ b/contains-duplicate/sadie100.ts @@ -0,0 +1,19 @@ +/** +풀이 +- JS 집합 자료구조인 Set을 활용합니다. Set은 중복값이 들어올 경우 제거되어 고유한 값들만 갖는 특성이 있습니다. +- nums를 Set으로 바꾸고 두 데이터의 length(Set의 경우 size 접근자 사용)를 비교합니다. + - 다를 경우 : Set에서 중복값이 제거된 경우이므로 true를 반환합니다. + - 같을 경우 : 중복값이 없던 경우이므로 false를 반환합니다. + +Big O +- Time Complexity: O(N) (N은 nums의 길이) + new Set(nums)를 만드는 과정에서 배열의 모든 원소를 순회하며 Set에 삽입합니다. (삽입 평균 시간 O(1)) + numSet.size 및 nums.length는 각각 O(1)이므로 총 O(N)의 시간복잡도를 갖습니다. +- Space Complexity: O(N) + Set에 최대 n개의 요소가 저장되므로 O(N)의 공간복잡도를 갖습니다. + */ + +function containsDuplicate(nums: number[]): boolean { + const numSet = new Set(nums) + return numSet.size !== nums.length +} diff --git a/house-robber/sadie100.ts b/house-robber/sadie100.ts new file mode 100644 index 000000000..21e7a6cbc --- /dev/null +++ b/house-robber/sadie100.ts @@ -0,0 +1,25 @@ +/** +dp 배열을 만들고 각 원소 순서에서 최대의 값을 계산, 리턴한다 + +시간복잡도 +O(N) : 단일 순회 + +공간복잡도 +O(N) : dp 배열 + */ + +function rob(nums: number[]): number { + const dp = [] + + for (let i = 0; i < nums.length; i++) { + if (i < 1) { + dp[i] = nums[i] + } else if (i < 2) { + dp[i] = Math.max(dp[i - 1], nums[i]) + } else { + dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]) + } + } + + return dp.at(-1) +} diff --git a/longest-consecutive-sequence/sadie100.ts b/longest-consecutive-sequence/sadie100.ts new file mode 100644 index 000000000..1e8eb33d0 --- /dev/null +++ b/longest-consecutive-sequence/sadie100.ts @@ -0,0 +1,30 @@ +/** +nums를 Set으로 만들어서 중복을 제거하고 순회하면서 시작점(n-1이 Set에 없는 수)을 찾아 연속된 수를 찾아가며 length를 계산한다. +시작점이 아닌 num(set에 num-1이 있는 경우)는 순회하지 않는다. + +시간복잡도 +O(N) : 이중 반복문이지만 시작점에서만 탐색하므로 깊은 중복 순회가 없음 + */ + +function longestConsecutive(nums: number[]): number { + if (nums.length === 0) return 0 + const numSet = new Set(nums) + let result = 1 + + for (let num of numSet) { + if (numSet.has(num - 1)) { + continue + } + + let next = num + 1 + let count = 1 + while (numSet.has(next)) { + count += 1 + next += 1 + } + + result = Math.max(result, count) + } + + return result +} diff --git a/top-k-frequent-elements/sadie100.ts b/top-k-frequent-elements/sadie100.ts new file mode 100644 index 000000000..4d3c40f27 --- /dev/null +++ b/top-k-frequent-elements/sadie100.ts @@ -0,0 +1,27 @@ +/** +nums를 순회하며 {[num]: 등장횟수} 형태의 데이터로 바꾸고, 순회가 끝난후 +해당 데이터를 등장횟수 기준으로 내림차순 정렬하여 상위 k개를 리턴한다 + +O(N) +시간복잡도 : O(NlogN) +nums 순회 - O(N), 객체 배열화 - O(N), 정렬 - O(NLogN) 도합 O(NLogN) + */ + +function topKFrequent(nums: number[], k: number): number[] { + const countObj: Record = {} + + for (let num of nums) { + if (num in countObj) { + countObj[num] += 1 + } else { + countObj[num] = 1 + } + } + + const countArr = Object.entries(countObj) + .sort((a, b) => b[1] - a[1]) + .map(([num, cnt]) => Number(num)) + .filter((val, idx) => idx < k) + + return countArr +} diff --git a/two-sum/sadie100.ts b/two-sum/sadie100.ts new file mode 100644 index 000000000..b44e079a0 --- /dev/null +++ b/two-sum/sadie100.ts @@ -0,0 +1,26 @@ +/* +풀이 +해시맵을 이용해 현재 값의 보수(target - num)가 이미 등장했는지 확인한다. + + +시간복잡도 +O(N) - nums 순회 + +공간복잡도 +O(N) - numObj 생성 +*/ + +function twoSum(nums: number[], target: number): number[] { + const numObj: { [key: number]: number } = {} + + for (let i = 0; i < nums.length; i++) { + const num = nums[i] + if (target - num in numObj) { + return [i, numObj[target - num]] + } else { + numObj[num] = i + } + } + + return [] +}