diff --git a/climbing-stairs/hyejj19.ts b/climbing-stairs/hyejj19.ts new file mode 100644 index 0000000000..ee9de64cfb --- /dev/null +++ b/climbing-stairs/hyejj19.ts @@ -0,0 +1,34 @@ +function climbStairs(n: number, memo = {}): number { + // 재귀 종료조건 + if (n === 1) return 1; + if (n === 2) return 2; + + // 값이 메모에 존재하면 해당 값을 리턴 + if (memo[n] !== undefined) return memo[n]; + + // 아니라면 계산 후 메모이징 + memo[n] = climbStairs(n - 1, memo) + climbStairs(n - 2, memo); + + return memo[n]; +} + +// 2번째 시도 +// 1. 재귀 접근의 경우 메모리와 콜스택 과부하가 있을 수 있음. +// 2. 모든 경우의 수가 아닌 바로 직전 단계까지의 합산 값만 있어도 결과 도출이 가능하다. + +function climbStairs(n: number): number { + if (n === 1) return 1; + if (n === 2) return 2; + + let prev2 = 1; // n-2번째 + let prev1 = 2; // n-1번째 + let cur = 0; + + for (let i = 3; i <= n; i++) { + cur = prev2 + prev1; + prev2 = prev1; + prev1 = cur; + } + + return cur; +} diff --git a/product-of-array-except-self/hyejj19.ts b/product-of-array-except-self/hyejj19.ts new file mode 100644 index 0000000000..ffa35ca842 --- /dev/null +++ b/product-of-array-except-self/hyejj19.ts @@ -0,0 +1,45 @@ +// answer[i] -> nums[i] 제외한 나머지의 곱 +function productExceptSelf(nums: number[]): number[] { + let left = []; + let right = []; + let acc = 1; + + for (let i = 0; i < nums.length; i++) { + left[i] = acc; // 이전결과까지의 누적값을 i번째에 저장 + acc = acc * nums[i]; // 다음 저장을 위해 업데이트 + } + + acc = 1; + for (let i = nums.length - 1; i >= 0; i--) { + right[i] = acc; + acc = acc * nums[i]; + } + + let answer = []; + for (let i = 0; i < nums.length; i++) { + answer.push(left[i] * right[i]); + } + + return answer; +} + +// 2번째 시도 +// 공간복잡도를 O(1)로 줄일 수 있을까? +// answer[i] -> nums[i] 제외한 나머지의 곱 +function productExceptSelf(nums: number[]): number[] { + let answer = []; + let acc = 1; + + for (let i = 0; i < nums.length; i++) { + answer[i] = acc; // 이전결과까지의 누적값을 i번째에 저장 + acc = acc * nums[i]; // 다음 저장을 위해 업데이트 + } + + acc = 1; + for (let i = nums.length - 1; i >= 0; i--) { + answer[i] = answer[i] * acc; + acc = acc * nums[i]; + } + + return answer; +} diff --git a/valid-anagram/hyejj19.ts b/valid-anagram/hyejj19.ts new file mode 100644 index 0000000000..edad998195 --- /dev/null +++ b/valid-anagram/hyejj19.ts @@ -0,0 +1,46 @@ +// 1번째 접근 +// 길이가 같지 않다면 무조건 예외이므로 false. +// 두 문자열을 다 Map 으로 만든다. +// 하나의 Map 의 글자와 다른 하나의 Map 에 있는 글자를 비교하며 존재 여부와 카운트 일치 여부를 확인한다. + +function isAnagram(s: string, t: string): boolean { + if (s.length !== t.length) return false; + + const sMap = new Map(); + for (const sChar of s) { + sMap.set(sChar, (sMap.get(sChar) || 0) + 1); + } + const tMap = new Map(); + for (const tChar of t) { + tMap.set(tChar, (tMap.get(tChar) || 0) + 1); + } + + for (const [char, count] of tMap) { + if (!sMap.get(char)) return false; + if (sMap.get(char) !== count) return false; + } + + return true; +} + +// 2번째 접근 +// Map을 한 개만 만들고도 비교가 가능하지 않을까? +// 1. 하나의 문자열에 대한 Map 을 만든다. +// 2. 나머지 문자열을 순회하며 해당 문자열 카운트를 Map 에서 조회 +// 3. 만약 카운트가 0이라면 false +// 4. 조회가 가능하다면 Map 의 카운트를 -1. +function isAnagram(s: string, t: string): boolean { + if (s.length !== t.length) return false; + + const sMap = new Map(); + for (const sChar of s) { + sMap.set(sChar, (sMap.get(sChar) || 0) + 1); + } + for (const char of t) { + const count = sMap.get(char) || 0; + if (count === 0) return false; + sMap.set(char, count - 1); + } + + return true; +}