From 606b9ae6e9fd64335302420099dc07a05c1296d2 Mon Sep 17 00:00:00 2001 From: BaeKwangho Date: Thu, 20 Nov 2025 23:23:16 +0900 Subject: [PATCH 1/3] week2 attempt 3 --- validate-binary-search-tree/Baekwangho.ts | 90 +++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 validate-binary-search-tree/Baekwangho.ts diff --git a/validate-binary-search-tree/Baekwangho.ts b/validate-binary-search-tree/Baekwangho.ts new file mode 100644 index 0000000000..014be5934d --- /dev/null +++ b/validate-binary-search-tree/Baekwangho.ts @@ -0,0 +1,90 @@ +/** + * Definition for a binary tree node. + * 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) + * } + * } + */ + +/** + 1차 시도 + +function isValidBST(root: TreeNode | null): boolean { + let result = true; + + function validate(node: TreeNode) { + if (node.left) { + if (node.val > node.left.val) { + validate(node.left); + } else { + result = false; + } + } + + if (node.right) { + if (node.val < node.right.val) { + validate(node.right); + } else { + result = false; + } + } + } + + validate(root); + return result; +} + */ + +interface TreeNode { + val: number; + left: TreeNode; + right: TreeNode; +} + +/** 2차 시도 실패 */ +function isValidBST(root: TreeNode | null): boolean { + let result = true; + + function validate(node: TreeNode, lstandard?: number, rstandard?: number) { + if (node.left) { + if (lstandard !== undefined && lstandard > node.left.val) { + result = false; + } + + if (rstandard !== undefined && rstandard < node.left.val) { + result = false; + } + + if (node.val > node.left.val) { + validate(node.left, undefined, node.val); + } else { + result = false; + } + } + + if (node.right) { + if (lstandard !== undefined && lstandard > node.right.val) { + result = false; + } + + if (rstandard !== undefined && rstandard < node.right.val) { + result = false; + } + + if (node.val < node.right.val) { + validate(node.right, node.val, undefined); + } else { + result = false; + } + } + } + + validate(root!); + return result; +} From cde9f5c2343fa2c7e89c45f6bd38f3b75dc2ccfb Mon Sep 17 00:00:00 2001 From: BaeKwangho Date: Wed, 10 Dec 2025 22:23:16 +0900 Subject: [PATCH 2/3] week5 --- best-time-to-buy-and-sell-stock/Baekwangho.ts | 68 +++++++++++++++++++ group-anagrams/Baekwangho.ts | 22 ++++++ implement-trie-prefix-tree/Baekwangho.ts | 65 ++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 best-time-to-buy-and-sell-stock/Baekwangho.ts create mode 100644 group-anagrams/Baekwangho.ts create mode 100644 implement-trie-prefix-tree/Baekwangho.ts diff --git a/best-time-to-buy-and-sell-stock/Baekwangho.ts b/best-time-to-buy-and-sell-stock/Baekwangho.ts new file mode 100644 index 0000000000..facc4ca995 --- /dev/null +++ b/best-time-to-buy-and-sell-stock/Baekwangho.ts @@ -0,0 +1,68 @@ +/** +일단 가장 단순하게 생각했을 때, +n^2 의 시간 복잡도를 가지면 모든 경우의 수를 확인가능하다. + +function maxProfit(prices: number[]): number { + let maximum = 0 + for(let i=0; i maximum) maximum = prices[j] - prices[i] + } + } + return maximum +}; + */ + +/** +하지만 시간 초과가 발생하니, 다른 방법을 써보자. +이익을 구하기 위해서는 가장 낮은 지점과 가장 큰 지점에 대한 탐색이 필요하다. +가장 낮은 지점은 큰 지점보다 앞에 위치해야 한다. + +만약 투 포인터로 양 끝에서 오면서 왼쪽은 가장 낮은 것, 오른쪽은 가장 높은 것을 확인해서 +두 포인터가 만날 때 차분을 구한다면? + +function maxProfit(prices: number[]): number { + let left = prices[0]; + let right = prices[prices.length-1]; + for (let i=0; i (prices.length - 1 - i)) { + break + } + + if (prices[i] < left) { + left = prices[i] + } + + if (prices[prices.length - 1 - i] > right) { + right = prices[prices.length - 1 - i] + } + } + + return left > right ? 0 : right - left +}; +*/ + +/** +[3,2,6,5,0,3] 와 같은 경우에 일반화 되지 못한다. +정답을 기준으로, 큰 값 이후에는 그보다 큰 값이 없어야 하고, +작은 값 이전에는 그보다 작은 값이 없어야 한다. + +그렇다면 포인터를 이 기준에 맞게 급격히 옮겨볼까? +... +힌트를 보고 왔다. 단순하게 최저값을 항상 갱신해주면 되는구나. + */ +function maxProfit(prices: number[]): number { + let min = 10000; + let max = 0; + for (let i = 0; i < prices.length; i++) { + if (prices[i] < min) { + min = prices[i]; + continue; + } + + if (prices[i] - min > max) { + max = prices[i] - min; + } + } + return max; +} diff --git a/group-anagrams/Baekwangho.ts b/group-anagrams/Baekwangho.ts new file mode 100644 index 0000000000..65eccec3a4 --- /dev/null +++ b/group-anagrams/Baekwangho.ts @@ -0,0 +1,22 @@ +/** +3글자씩으로 구성된 각 문자열 배열을 순회하며, 각 문자열을 알파벳 순서로 정렬한 순서를 기준으로 +동일하다면 원래의 문자열을 key 로 하는 해시에 포함시켜보자 + +시간 복잡도: O(n log n) 공간 복잡도: O(n) 정도 나오지 않을까? + */ +function groupAnagrams(strs: string[]): string[][] { + const anaMap = new Map(); + + for (let i = 0; i < strs.length; i++) { + const hashKey = strs[i].split("").sort().join(""); + + const arr = anaMap.get(hashKey); + if (!arr) { + anaMap.set(hashKey, [strs[i]]); + } else { + anaMap.set(hashKey, [...arr, strs[i]]); + } + } + + return [...anaMap.values()]; +} diff --git a/implement-trie-prefix-tree/Baekwangho.ts b/implement-trie-prefix-tree/Baekwangho.ts new file mode 100644 index 0000000000..e8bd7b5f13 --- /dev/null +++ b/implement-trie-prefix-tree/Baekwangho.ts @@ -0,0 +1,65 @@ +/** +test case 를 분석해본 결과, 결국 문자열에 대한 트리를 구성해야 하는 것으로 보임 +트리는 노드로 구성할 수 있을 듯 하지만, 구현하지 않고 hash 의 연속을 만들어보는 것으로 하자. + +오래걸렸지만 한번에 성공! 시간 복잡도: O(n), 공간 복잡도: O(1) 정도인 듯 + */ +class Trie { + constructor(private letterHash: any = {}) {} + + insert(word: string): void { + let currentHash = this.letterHash; + + for (let i = 0; i < word.length; i++) { + const existHash = currentHash[word[i]]; + if (existHash) { + currentHash = existHash; + } else { + currentHash[word[i]] = {}; + currentHash = currentHash[word[i]]; + } + } + + currentHash["count"] = currentHash["count"] ? currentHash["count"] + 1 : 1; + } + + search(word: string): boolean { + let currentHash = this.letterHash; + + for (let i = 0; i < word.length; i++) { + const existHash = currentHash[word[i]]; + // console.log(`search ${word}`, JSON.stringify(existHash), word[i]) + if (existHash) { + currentHash = existHash; + } else { + return false; + } + } + + return !!currentHash["count"]; + } + + startsWith(prefix: string): boolean { + let currentHash = this.letterHash; + + for (let i = 0; i < prefix.length; i++) { + const existHash = currentHash[prefix[i]]; + // console.log(`startsWith ${prefix}`, JSON.stringify(existHash), prefix[i]) + if (existHash) { + currentHash = existHash; + } else { + return false; + } + } + + return true; + } +} + +/** + * Your Trie object will be instantiated and called as such: + * var obj = new Trie() + * obj.insert(word) + * var param_2 = obj.search(word) + * var param_3 = obj.startsWith(prefix) + */ From cd514df098df8f8d137110461b9249e180307097 Mon Sep 17 00:00:00 2001 From: BaeKwangho Date: Wed, 10 Dec 2025 22:26:52 +0900 Subject: [PATCH 3/3] remove week2 --- validate-binary-search-tree/Baekwangho.ts | 90 ----------------------- 1 file changed, 90 deletions(-) delete mode 100644 validate-binary-search-tree/Baekwangho.ts diff --git a/validate-binary-search-tree/Baekwangho.ts b/validate-binary-search-tree/Baekwangho.ts deleted file mode 100644 index 014be5934d..0000000000 --- a/validate-binary-search-tree/Baekwangho.ts +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Definition for a binary tree node. - * 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) - * } - * } - */ - -/** - 1차 시도 - -function isValidBST(root: TreeNode | null): boolean { - let result = true; - - function validate(node: TreeNode) { - if (node.left) { - if (node.val > node.left.val) { - validate(node.left); - } else { - result = false; - } - } - - if (node.right) { - if (node.val < node.right.val) { - validate(node.right); - } else { - result = false; - } - } - } - - validate(root); - return result; -} - */ - -interface TreeNode { - val: number; - left: TreeNode; - right: TreeNode; -} - -/** 2차 시도 실패 */ -function isValidBST(root: TreeNode | null): boolean { - let result = true; - - function validate(node: TreeNode, lstandard?: number, rstandard?: number) { - if (node.left) { - if (lstandard !== undefined && lstandard > node.left.val) { - result = false; - } - - if (rstandard !== undefined && rstandard < node.left.val) { - result = false; - } - - if (node.val > node.left.val) { - validate(node.left, undefined, node.val); - } else { - result = false; - } - } - - if (node.right) { - if (lstandard !== undefined && lstandard > node.right.val) { - result = false; - } - - if (rstandard !== undefined && rstandard < node.right.val) { - result = false; - } - - if (node.val < node.right.val) { - validate(node.right, node.val, undefined); - } else { - result = false; - } - } - } - - validate(root!); - return result; -}