From e8c532d54f96b5424e05289eab62c8f7276b457e Mon Sep 17 00:00:00 2001 From: soobing Date: Mon, 5 May 2025 15:37:24 +0900 Subject: [PATCH 1/5] feat(soobing): week6 > valid-parentheses --- valid-parentheses/soobing.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 valid-parentheses/soobing.ts diff --git a/valid-parentheses/soobing.ts b/valid-parentheses/soobing.ts new file mode 100644 index 000000000..a71c8e57a --- /dev/null +++ b/valid-parentheses/soobing.ts @@ -0,0 +1,15 @@ +function isValid(s: string): boolean { + const result: string[] = []; + const open = ["(", "[", "{"]; + const close = [")", "]", "}"]; + for (let i = 0; i < s.length; i++) { + if (open.includes(s[i])) { + result.push(s[i]); + } else { + const index = close.findIndex((item) => item === s[i]); + const popedItem = result.pop(); + if (popedItem !== open[index]) return false; + } + } + return result.length === 0; +} From 01770657f5355ba8c9f8948a4cf0cb85629c6fbd Mon Sep 17 00:00:00 2001 From: soobing Date: Sat, 10 May 2025 10:36:07 +0900 Subject: [PATCH 2/5] feat(soobing): week6 > container-with-most-water --- container-with-most-water/soobing.ts | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 container-with-most-water/soobing.ts diff --git a/container-with-most-water/soobing.ts b/container-with-most-water/soobing.ts new file mode 100644 index 000000000..085eaa704 --- /dev/null +++ b/container-with-most-water/soobing.ts @@ -0,0 +1,33 @@ +/** + * + * 문제 설명 + * 가장 많이 담을 수 있는 물의 용기 구하기 + * - height: 높이(n)를 담고 있는 배열 = y축 값 + * - index: x축 값 + * + * 아이디어 + * 1. 브루트포스 방식 O(n^2) + * - 모든 쌍을 비교하여 최대 물의 양 찾기 + * + * 2. 투 포인터 방식 O(n) + * - 왼쪽과 오른쪽 포인터를 이용하여 최대 물의 양 찾기 + * - 같은 높이의 두 라인이 있는 경우 한쪽만 움직여도 최적의 해를 찾는데는 문제 없음 + */ +function maxArea(height: number[]): number { + let left = 0; + let right = height.length - 1; + let result = 0; + while (left < right) { + const x = right - left; + const y = Math.min(height[left], height[right]); + result = Math.max(x * y, result); + + if (height[left] < height[right]) { + left++; + } else { + right--; + } + } + + return result; +} From 7c5ee41158a84715374fa59a43c83db603972fb1 Mon Sep 17 00:00:00 2001 From: soobing Date: Sat, 10 May 2025 11:32:23 +0900 Subject: [PATCH 3/5] feat(soobing): week6 > design-add-and-search-words-data-structure --- .../soobing.ts | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 design-add-and-search-words-data-structure/soobing.ts diff --git a/design-add-and-search-words-data-structure/soobing.ts b/design-add-and-search-words-data-structure/soobing.ts new file mode 100644 index 000000000..002bbc57d --- /dev/null +++ b/design-add-and-search-words-data-structure/soobing.ts @@ -0,0 +1,64 @@ +/** + * + * 문제 설명 + * - 문자열 추가/검색에 효율적인 데이터 구조 설계 + * + * 아이디어 + * 1) 배열에 추가, 순차적으로 검색(.의 경우 정규식 사용) + * - Time Limit Exceeded (TLE) 발생 + * + * 2) Trie 구조로 저장, 검색은 dfs + * - 문자열 검색어 최적화 = Trie + * + */ + +class TrieNode { + children: Map = new Map(); + isEnd: boolean = false; +} + +class WordDictionary { + root: TrieNode; + + constructor() { + this.root = new TrieNode(); + } + + addWord(word: string): void { + let node = this.root; + for (let char of word) { + if (!node.children.has(char)) { + node.children.set(char, new TrieNode()); + } + node = node.children.get(char)!; + } + node.isEnd = true; + } + + search(word: string): boolean { + const dfs = (node: TrieNode, i: number) => { + if (i === word.length) return node.isEnd; + + const char = word[i]; + + if (char === ".") { + for (let child of node.children.values()) { + if (dfs(child, i + 1)) return true; + } + return false; + } else { + const next = node.children.get(char); + return next ? dfs(next, i + 1) : false; + } + }; + + return dfs(this.root, 0); + } +} + +/** + * Your WordDictionary object will be instantiated and called as such: + * var obj = new WordDictionary() + * obj.addWord(word) + * var param_2 = obj.search(word) + */ From bfdf3b2ed11d6addfd1c6a1afd038a3518d66116 Mon Sep 17 00:00:00 2001 From: soobing Date: Sun, 11 May 2025 00:09:21 +0900 Subject: [PATCH 4/5] feat(soobing): week6 > longest-increasing-subsequence --- longest-increasing-subsequence/soobing.ts | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 longest-increasing-subsequence/soobing.ts diff --git a/longest-increasing-subsequence/soobing.ts b/longest-increasing-subsequence/soobing.ts new file mode 100644 index 000000000..a7ead1d64 --- /dev/null +++ b/longest-increasing-subsequence/soobing.ts @@ -0,0 +1,33 @@ +/** + * + * 문제 설명 + * - Longest Increasing Subsequence(LIS) + * - 최장 증가 부분 수열 + * + * 아이디어 + * 1) Brute Force + * - 시간복잡도가 O(2^n)이라서 TLE(Time Limit Exceed) 발생 + * - 구현은 backtracking으로 해야함. + * + * 2) Dynamic Programming + * - 시간복잡도: O(n^2) + * - nums[i]의 이전 원소들 중 가장 긴 LIS에 1을 더해서 저장 + * + * 3) Binary Search + * - 시간 복잡도: (O(n log n)) + * - 다음 기회에 풀어봐야지.. + * + */ +function lengthOfLIS(nums: number[]): number { + const dp = Array(nums.length).fill(1); + + for (let i = 0; i < nums.length; i++) { + for (let j = 0; j < i; j++) { + if (nums[j] < nums[i]) { + dp[i] = Math.max(dp[i], dp[j] + 1); + } + } + } + + return Math.max(...dp); +} From b807172f4a6cdc006b6f1a7e024fe7deeed92bf9 Mon Sep 17 00:00:00 2001 From: soobing Date: Sun, 11 May 2025 00:33:18 +0900 Subject: [PATCH 5/5] feat(soobing): week6 > spiral-matrix --- spiral-matrix/soobing.ts | 49 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 spiral-matrix/soobing.ts diff --git a/spiral-matrix/soobing.ts b/spiral-matrix/soobing.ts new file mode 100644 index 000000000..f439f730b --- /dev/null +++ b/spiral-matrix/soobing.ts @@ -0,0 +1,49 @@ +/** + * + * 문제 설명 + * - 2차원 배열을 나선형으로 데이터 순회하여 1차원 배열로 담기 + * - 문제 풀이 타입의 알고리즘 문제 같음 + * + * 아이디어 + * 1) 경계를 정하고 오른쪽, 아래, 왼쪽, 위로 순회한다. + * + */ +function spiralOrder(matrix: number[][]): number[] { + let left = 0; + let top = 0; + let right = matrix[0].length - 1; + let bottom = matrix.length - 1; + + const result: number[] = []; + + while (left <= right && top <= bottom) { + // 오른쪽 + for (let i = left; i <= right; i++) { + result.push(matrix[top][i]); + } + top++; + + // 아래 + for (let i = top; i <= bottom; i++) { + result.push(matrix[i][right]); + } + right--; + + // 왼쪽 + if (top <= bottom) { + for (let i = right; i >= left; i--) { + result.push(matrix[bottom][i]); + } + bottom--; + } + + // 위쪽 + if (left <= right) { + for (let i = bottom; i >= top; i--) { + result.push(matrix[i][left]); + } + left++; + } + } + return result; +}