From f1aa488cce2ce198b2cadd931c92e4d13e3aa82d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9D=80=EB=AF=BC=20=28E=2EM=2E=20Jamie=20Lee=29?= <100mgml@gmail.com> Date: Thu, 2 Apr 2026 14:59:21 +0900 Subject: [PATCH 1/4] add solution for best time to buy and sell stock problem --- best-time-to-buy-and-sell-stock/gcount85.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 best-time-to-buy-and-sell-stock/gcount85.py diff --git a/best-time-to-buy-and-sell-stock/gcount85.py b/best-time-to-buy-and-sell-stock/gcount85.py new file mode 100644 index 000000000..238bf8cf5 --- /dev/null +++ b/best-time-to-buy-and-sell-stock/gcount85.py @@ -0,0 +1,21 @@ +""" +# Approach +지금까지의 최저 가격을 갱신함과 동시에 최선의 이익도 업데이트합니다. + +# Complexity +- Time complexity: O(N) + +- Space complexity: O(1) +""" + + +class Solution: + def maxProfit(self, prices: list[int]) -> int: + min_price = float("inf") + answer = 0 + + for price in prices: + min_price = min(min_price, price) + answer = max(answer, price - min_price) + + return answer From 4230e0b4eb3ccc869a4e7a2f9aa3a003b18ad78a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9D=80=EB=AF=BC=20=28E=2EM=2E=20Jamie=20Lee=29?= <100mgml@gmail.com> Date: Thu, 2 Apr 2026 15:13:28 +0900 Subject: [PATCH 2/4] add solution for grouping anagrams --- group-anagrams/gcount85.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 group-anagrams/gcount85.py diff --git a/group-anagrams/gcount85.py b/group-anagrams/gcount85.py new file mode 100644 index 000000000..65d4890dd --- /dev/null +++ b/group-anagrams/gcount85.py @@ -0,0 +1,21 @@ +""" +# Approach +strs 배열을 순회하며 문자열을 정규화(정렬)하고, +정규화 값이 같은 원소들끼리 모이도록 딕셔너리에 추가하여 최종 값을 반환한다. + +# Complexity +strs의 길이를 N, 문자열의 길이를 K라고 할 때, + +- Time complexity: O(N*KlogK) +- Space complexity: O(N*K) +""" + +from collections import defaultdict + + +class Solution: + def groupAnagrams(self, strs: list[str]) -> list[list[str]]: + anagram = defaultdict(list) # normalized str : str list + for s in strs: + anagram["".join(sorted(s))].append(s) + return list(anagram.values()) From dafa5ee9c7578daf3d25318bc092c39ba539b2ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9D=80=EB=AF=BC=20=28E=2EM=2E=20Jamie=20Lee=29?= <100mgml@gmail.com> Date: Fri, 3 Apr 2026 15:36:45 +0900 Subject: [PATCH 3/4] add solution for word break problem --- word-break/gcount85.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 word-break/gcount85.py diff --git a/word-break/gcount85.py b/word-break/gcount85.py new file mode 100644 index 000000000..ef5e4f014 --- /dev/null +++ b/word-break/gcount85.py @@ -0,0 +1,35 @@ +""" +# Intuition +wordDict를 word들의 길이로 분류하고, +s의 각 위치까지의 문자열을 완성할 수 있는지 dp 배열로 확인합니다. + +# Complexity +wordDict의 길이를 N, s의 길이를 K +- Time complexity: O(N+K) +- Space complexity: O(N+K) +""" + +from collections import defaultdict + + +class Solution: + def wordBreak(self, s: str, wordDict: list[str]) -> bool: + n = len(s) + dp = [False] * (n + 1) + word_dict = defaultdict(set) + for word in wordDict: + word_dict[len(word)].add(word) + + dp[0] = True + for i in range(1, n + 1): + for ( + k, + v, + ) in word_dict.items(): + if i + k - 1 > n: + continue + if dp[i - 1] == False: + continue + if s[i - 1 : i + k - 1] in v: + dp[i + k - 1] = True + return dp[n] From 6adf92bf163c1e37d37e2d2a6a46365ec391aeb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9D=80=EB=AF=BC=20=28E=2EM=2E=20Jamie=20Lee=29?= <100mgml@gmail.com> Date: Fri, 3 Apr 2026 16:13:34 +0900 Subject: [PATCH 4/4] Add Implement Trie solution --- implement-trie-prefix-tree/gcount85.py | 41 ++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 implement-trie-prefix-tree/gcount85.py diff --git a/implement-trie-prefix-tree/gcount85.py b/implement-trie-prefix-tree/gcount85.py new file mode 100644 index 000000000..764e78800 --- /dev/null +++ b/implement-trie-prefix-tree/gcount85.py @@ -0,0 +1,41 @@ +class TrieNode: + def __init__(self): + self.children = {} + self.is_end = False + + +class Trie: + + def __init__(self): + self.root = TrieNode() + + def insert(self, word: str) -> None: + node = self.root + for ch in word: + if ch not in node.children: + node.children[ch] = TrieNode() + node = node.children[ch] + node.is_end = True + + def search(self, word: str) -> bool: + node = self.root + for ch in word: + if ch not in node.children: + return False + node = node.children[ch] + return node.is_end + + def startsWith(self, prefix: str) -> bool: + node = self.root + for ch in prefix: + if ch not in node.children: + return False + node = node.children[ch] + return True + + +# Your Trie object will be instantiated and called as such: +# obj = Trie() +# obj.insert(word) +# param_2 = obj.search(word) +# param_3 = obj.startsWith(prefix)