diff --git a/clone-graph/HoonDongKang.ts b/clone-graph/HoonDongKang.ts new file mode 100644 index 000000000..081b8d18e --- /dev/null +++ b/clone-graph/HoonDongKang.ts @@ -0,0 +1,65 @@ +/** + * [Problem]: [133] Clone Graph + * (https://leetcode.com/problems/longest-repeating-character-replacement/description/) + */ + +// Definition for _Node. +class _Node { + val: number; + neighbors: _Node[]; + + constructor(val?: number, neighbors?: _Node[]) { + this.val = val === undefined ? 0 : val; + this.neighbors = neighbors === undefined ? [] : neighbors; + } +} + +function cloneGraph(node: _Node | null): _Node | null { + //시간복잡도 O(n) + //공간복잡도 O(n) + function dfsFunc(node: _Node | null): _Node | null { + if (!node) return null; + const map = new Map<_Node, _Node>(); + + function dfs(node: _Node): _Node { + if (map.has(node)) return map.get(node)!; + + const copy = new _Node(node.val); + map.set(node, copy); + + for (const neighbor of node.neighbors) { + copy.neighbors.push(dfs(neighbor)); + } + + return copy; + } + + return dfs(node); + } + //시간복잡도 O(n) + //공간복잡도 O(n) + function bfsFunc(node: _Node | null): _Node | null { + if (!node) return null; + + const map = new Map<_Node, _Node>(); + const queue: _Node[] = []; + + const clone = new _Node(node.val); + map.set(node, clone); + queue.push(node); + + while (queue.length > 0) { + const cur = queue.shift()!; + + for (const neighbor of cur.neighbors) { + if (!map.has(neighbor)) { + map.set(neighbor, new _Node(neighbor.val)); + queue.push(neighbor); + } + + map.get(cur)!.neighbors.push(map.get(neighbor)!); + } + } + return clone; + } +} diff --git a/longest-common-subsequence/HoonDongKang.ts b/longest-common-subsequence/HoonDongKang.ts new file mode 100644 index 000000000..0bc13b28b --- /dev/null +++ b/longest-common-subsequence/HoonDongKang.ts @@ -0,0 +1,69 @@ +/** + * [Problem]: [1143] Longest Common Subsequence + * (https://leetcode.com/problems/longest-common-subsequence/description/) + */ +function longestCommonSubsequence(text1: string, text2: string): number { + //시간복잡도 O(2^n) + //공간복잡도 O(n) + // Time Limit Exceeded + function dfsFunc(text1: string, text2: string): number { + function dfs(i: number, j: number): number { + if (i === text1.length || j === text2.length) return 0; + + if (text1[i] === text2[j]) { + return 1 + dfs(i + 1, j + 1); + } else { + return Math.max(dfs(i, j + 1), dfs(i + 1, j)); + } + } + + return dfs(0, 0); + } + + //시간복잡도 O(n) + //공간복잡도 O(n) + function memoizationFunc(text1: string, text2: string): number { + const memo = new Map(); + + function dfs(i: number, j: number) { + if (i === text1.length || j === text2.length) return 0; + + const key = `${i}, ${j}`; + if (memo.has(key)) return memo.get(key)!; + + let result = 0; + if (text1[i] === text2[j]) { + result = 1 + dfs(i + 1, j + 1); + } else { + result = Math.max(dfs(i, j + 1), dfs(i + 1, j)); + } + + memo.set(key, result); + return result; + } + + return dfs(0, 0); + } + + //시간복잡도 O(n) + //공간복잡도 O(n) + function dpFunc(tex1: string, text2: string): number { + const length1 = text1.length; + const length2 = text2.length; + const dp: number[][] = Array.from({ length: length1 + 1 }, () => + Array(length2 + 1).fill(0) + ); + + for (let i = 1; i <= length1; i++) { + for (let j = 1; j <= length2; j++) { + if (text1[i - 1] === text2[j - 1]) { + dp[i][j] = 1 + dp[i - 1][j - 1]; + } else { + dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); + } + } + } + + return dp[length1][length2]; + } +} diff --git a/longest-repeating-character-replacement/HoonDongKang.ts b/longest-repeating-character-replacement/HoonDongKang.ts new file mode 100644 index 000000000..42cf3ef72 --- /dev/null +++ b/longest-repeating-character-replacement/HoonDongKang.ts @@ -0,0 +1,27 @@ +/** + * [Problem]: [424] Longest Repeating Character Replacement + * (https://leetcode.com/problems/longest-repeating-character-replacement/description/) + */ +function characterReplacement(s: string, k: number): number { + //시간복잡도 O(n) + //공간복잡도 O(n) + let left = 0; + let right = 0; + let result = 0; + let map = new Map(); + + while (right < s.length) { + map.set(s[right], (map.get(s[right]) || 0) + 1); + + const maxFreq = Math.max(...Array.from(map.values())); + if (right - left + 1 - maxFreq > k) { + map.set(s[left], map.get(s[left])! - 1); + left++; + } + + result = Math.max(result, right - left + 1); + right++; + } + + return result; +} diff --git a/palindromic-substrings/HoonDongKang.ts b/palindromic-substrings/HoonDongKang.ts new file mode 100644 index 000000000..d735b2a92 --- /dev/null +++ b/palindromic-substrings/HoonDongKang.ts @@ -0,0 +1,57 @@ +/** + * [Problem]: [647] Palindromic Substrings + * (https://leetcode.com/problems/palindromic-substrings/description/) + */ + +function countSubstrings(s: string): number { + //시간복잡도 O(n^3) + //공간복잡도 O(1) + function bruteForceFunc(s: string): number { + let count = 0; + + for (let i = 0; i < s.length; i++) { + for (let j = i; j < s.length; j++) { + if (isPanlindrome(i, j)) count++; + } + } + + function isPanlindrome(left: number, right: number): boolean { + while (left < right) { + if (s[left] !== s[right]) return false; + left++; + right--; + } + + return true; + } + + return count; + } + //시간복잡도 O(n^2) + //공간복잡도 O(n^2) + function dpFunc(s: string): number { + const dp = new Map(); + let count = 0; + + for (let end = 0; end < s.length; end++) { + for (let start = end; start >= 0; start--) { + const key = `${start},${end}`; + if (start === end) { + dp.set(key, true); + } else if (start + 1 === end) { + dp.set(key, s[start] === s[end]); + } else { + const innerKey = `${start + 1},${end - 1}`; + const isInnerPalindrome = dp.get(innerKey) || false; + dp.set(key, s[start] === s[end] && isInnerPalindrome); + } + + if (dp.get(key)) { + count++; + } + } + } + + return count; + } +} diff --git a/reverse-bits/HoonDongKang.ts b/reverse-bits/HoonDongKang.ts new file mode 100644 index 000000000..a28644a80 --- /dev/null +++ b/reverse-bits/HoonDongKang.ts @@ -0,0 +1,37 @@ +/** + * [Problem]: [190] Reverse Bits + * (https://leetcode.com/problems/reverse-bits/description/) + */ +function reverseBits(n: number): number { + //시간복잡도 O(1) + //공간복잡도 O(1) + function stackFunc(n: number): number { + const stack: number[] = []; + let output = 0; + let scale = 1; + + while (stack.length < 32) { + stack.push(n % 2); + n = Math.floor(n / 2); + } + + while (stack.length) { + output += stack.pop()! * scale; + scale *= 2; + } + + return output; + } + //시간복잡도 O(1) + //공간복잡도 O(1) + function bitFunc(n: number): number { + let result = 0; + for (let i = 0; i < 32; i++) { + result <<= 1; + result |= n & 1; + n >>>= 1; + } + + return result >>> 0; + } +}