diff --git a/3sum/soobing2.ts b/3sum/soobing2.ts new file mode 100644 index 000000000..02652d0a1 --- /dev/null +++ b/3sum/soobing2.ts @@ -0,0 +1,42 @@ +/** + * 문제 유형 + * - Array (정렬 + 투포인터) + * + * 문제 설명 + * - 3개의 수를 더해서 0이 되는 경우를 찾아서 배열로 반환하기 + * + * 아이디어 + * 1) 정렬 후 투포인터 사용, 중복 제거 + + */ +function threeSum(nums: number[]): number[][] { + const result: number[][] = []; + + // sorting + nums.sort((a, b) => a - b); + + for (let i = 0; i < nums.length - 2; i++) { + // 중복 제거 + if (i > 0 && nums[i] === nums[i - 1]) continue; + + let left = i + 1; + let right = nums.length - 1; + while (left < right) { + const sum = nums[i] + nums[left] + nums[right]; + if (sum === 0) { + result.push([nums[i], nums[left], nums[right]]); + left++; + right--; + + // 중복 제거 + while (left < right && nums[left] === nums[left - 1]) left++; + while (left < right && nums[right] === nums[right + 1]) right--; + } else if (sum < 0) { + left++; + } else { + right--; + } + } + } + return result; +} diff --git a/climbing-stairs/soobing.ts b/climbing-stairs/soobing.ts new file mode 100644 index 000000000..3a95e3a0d --- /dev/null +++ b/climbing-stairs/soobing.ts @@ -0,0 +1,34 @@ +/** + * 문제 유형 + * - DP (피보나치) + * + * 문제 설명 + * - 계단을 올라가는 방법의 수를 구하기 + * + * 아이디어 + * 1) 피보나치 수열 활용 + * - climbStairs(n) = climbStairs(n-1) + climbStairs(n-2) + */ +function climbStairsBottomUp(n: number): number { + function fibonacci(n: number, memo = new Map()) { + if (n === 1) return 1; + if (n === 2) return 2; + + if (memo.has(n)) return memo.get(n); + const result = fibonacci(n - 1, memo) + fibonacci(n - 2, memo); + memo.set(n, result); + return result; + } + return fibonacci(n); +} + +function climbStairsTopDown(n: number): number { + const dp = new Array(n + 1).fill(0); + dp[1] = 1; + dp[2] = 2; + + for (let i = 3; i <= n; i++) { + dp[i] = dp[i - 1] + dp[i - 2]; + } + return dp[n]; +} diff --git a/product-of-array-except-self/soobing2.ts b/product-of-array-except-self/soobing2.ts new file mode 100644 index 000000000..cad2afe70 --- /dev/null +++ b/product-of-array-except-self/soobing2.ts @@ -0,0 +1,52 @@ +/** + * 문제 유형 + * - Array + * + * 문제 설명 + * - 자기 자신을 제외한 나머지의 곱 구하기 + * + * 아이디어 + * 1) Array - 자기 자신보다 이전, 이후 의 누적곱(left, right) 구하고, 최종적으로 곱하기 + * 2) 0읠 제외한 나머지의 곱, 0의 갯수 카운트를 이용하여 조건에 따라 계산하기 + */ +function productExceptSelf(nums: number[]): number[] { + const answer = Array(nums.length).fill(0); + let zeroCount = 0; + const productWithoutZero = nums.reduce((acc, cur) => { + if (cur === 0) { + zeroCount++; + return acc; + } + return cur * acc; + }, 1); + + for (let i = 0; i < nums.length; i++) { + if (zeroCount > 0) { + if (nums[i]) answer[i] = 0; + else answer[i] = zeroCount > 1 ? 0 : productWithoutZero; + } else { + answer[i] = productWithoutZero / nums[i]; + } + } + return answer; +} + +function productExceptSelfArrayVersion(nums: number[]): number[] { + const answer = Array(nums.length); + const left = Array(nums.length).fill(1); + const right = Array(nums.length).fill(1); + + for (let i = 1; i < nums.length; i++) { + left[i] = left[i - 1] * nums[i - 1]; + } + + for (let i = nums.length - 2; i >= 0; i--) { + right[i] = right[i + 1] * nums[i + 1]; + } + + for (let i = 0; i < nums.length; i++) { + answer[i] = left[i] * right[i]; + } + + return answer; +} diff --git a/valid-anagram/soobing.ts b/valid-anagram/soobing.ts new file mode 100644 index 000000000..17869f5d5 --- /dev/null +++ b/valid-anagram/soobing.ts @@ -0,0 +1,52 @@ +/** + * 문제 유형 + * - String + * + * 문제 설명 + * - 두 문자열이 애너그램인지 확인하기 + * + * 아이디어 + * 1) 문자열을 맵으로 변환하고, 정렬 후 비교하기 + * 2) 문자열 정렬 없이 하나의 map으로 더하고 빼기하여 0인지 확인하기 + */ +function mapString(str: string) { + const map = new Map(); + for (let i = 0; i < str.length; i++) { + map.set(str[i], (map.get(str[i]) || 0) + 1); + } + return map; +} +function isAnagram(s: string, t: string): boolean { + const sMap = mapString(s); + const tMap = mapString(t); + + const sKeys = [...sMap.keys()].sort().join(""); + const tKeys = [...tMap.keys()].sort().join(""); + + if (sKeys !== tKeys) return false; + + for (let i = 0; i < sKeys.length; i++) { + const key = sKeys[i]; + if (sMap.get(key) !== tMap.get(key)) return false; + } + + return true; +} + +// 아이디어 2 +function isAnagramDeveloped(s: string, t: string): boolean { + if (s.length !== t.length) return false; + + const count = new Map(); + + for (let i = 0; i < s.length; i++) { + count.set(s[i], (count.get(s[i]) || 0) + 1); + count.set(t[i], (count.get(t[i]) || 0) - 1); + } + + for (const val of count.values()) { + if (val !== 0) return false; + } + + return true; +} diff --git a/validate-binary-search-tree/soobing.ts b/validate-binary-search-tree/soobing.ts new file mode 100644 index 000000000..cae6c35b9 --- /dev/null +++ b/validate-binary-search-tree/soobing.ts @@ -0,0 +1,39 @@ +/** + * 문제 유형 + * - Tree + * + * 문제 설명 + * - 이진 탐색 트리가 맞는지 확인하기 + * + * 아이디어 + * 1) 중위 순회 후 정렬된 배열인지 확인 + * + */ +class TreeNode { + val: number; + left: TreeNode | null; + right: TreeNode | null; + constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + this.val = val === undefined ? 0 : val; + this.left = left === undefined ? null : left; + this.right = right === undefined ? null : right; + } +} + +function isSorted(arr: number[]) { + for (let i = 1; i < arr.length; i++) { + if (arr[i - 1] >= arr[i]) return false; + } + return true; +} +function inorder(node: TreeNode | null, arr: number[]) { + if (node === null) return; + inorder(node.left, arr); + arr.push(node.val); + inorder(node.right, arr); +} +function isValidBST(root: TreeNode | null): boolean { + const sortedArray: number[] = []; + inorder(root, sortedArray); + return isSorted(sortedArray); +}