From d7123a4fa1dff054971875c3c3aa83897b878ca2 Mon Sep 17 00:00:00 2001 From: hoyeongkwak Date: Sat, 23 Aug 2025 12:53:22 +0900 Subject: [PATCH 1/2] Week 5 Solutions --- .../hoyeongkwak.py | 29 ++++++++++ group-anagrams/hoyeongkwak.py | 20 +++++++ implement-trie-prefix-tree/hoyeongkwak.py | 53 ++++++++++++++++++ word-break/hoyeongkwak.py | 56 +++++++++++++++++++ 4 files changed, 158 insertions(+) create mode 100644 best-time-to-buy-and-sell-stock/hoyeongkwak.py create mode 100644 group-anagrams/hoyeongkwak.py create mode 100644 implement-trie-prefix-tree/hoyeongkwak.py create mode 100644 word-break/hoyeongkwak.py diff --git a/best-time-to-buy-and-sell-stock/hoyeongkwak.py b/best-time-to-buy-and-sell-stock/hoyeongkwak.py new file mode 100644 index 000000000..250d08d89 --- /dev/null +++ b/best-time-to-buy-and-sell-stock/hoyeongkwak.py @@ -0,0 +1,29 @@ +''' +time complexity : O(n) +space complexity : O(2n) + +Algorithm : dp +주식 보유하는 경우: +- 이전에 이미 보유 : hold[i - 1] +- i번째 날 새로 사는 경우 : -prices[i] + +주식을 팔았을 떄: +- 이전에 이미 팜 : sold[i - 1] +- i번째 날 파는 경우 : hold[i-1] + prices[i] +''' + +class Solution: + def maxProfit(self, prices: List[int]) -> int: + if not prices or len(prices) < 2: + return 0 + n = len(prices) + hold = [0] * n + sold = [0] * n + + hold[0] = -prices[0] + sold[0] = 0 + + for i in range(1, n): + hold[i] = max(hold[i - 1], -prices[i]) + sold[i] = max(sold[i - 1], hold[i - 1] + prices[i]) + return sold[n - 1] diff --git a/group-anagrams/hoyeongkwak.py b/group-anagrams/hoyeongkwak.py new file mode 100644 index 000000000..98a38a32f --- /dev/null +++ b/group-anagrams/hoyeongkwak.py @@ -0,0 +1,20 @@ +''' +m : 문자열 길이 +n : 반복 +time complexity : O(m * n * log m) +space complexity : O(m * n) +algorithm : sort, hash, +각 문자열에 대해서 정렬을 하고, 정렬을 했을 때 동일한 문자에 대해서 hash table에 정렬 전 문자열을 추가 +그리고 마지막에 list 형태로 hash table의 value에 대해서 돌려 준다 +nat -> ant +tan -> ant +''' +class Solution: + def groupAnagrams(self, strs: List[str]) -> List[List[str]]: + strResult = {} + for str in strs: + sortedStr = ''.join(sorted(str)) + if sortedStr not in strResult: + strResult[sortedStr] = [] + strResult[sortedStr].append(str) + return list(strResult.values()) diff --git a/implement-trie-prefix-tree/hoyeongkwak.py b/implement-trie-prefix-tree/hoyeongkwak.py new file mode 100644 index 000000000..bce628bd5 --- /dev/null +++ b/implement-trie-prefix-tree/hoyeongkwak.py @@ -0,0 +1,53 @@ +''' +insert +time complexity : O(m) +space complexity : O(m) + +search +time complexity : O(m) +space complexity : O(1) + +startWith +time complexity : O(m) +space complexity : O(1) +''' + +class TriedNode: + def __init__(self): + self.children = {} + self.isEnd = False + +class Trie: + def __init__(self): + self.root = TriedNode() + + def insert(self, word: str) -> None: + node = self.root + for char in word: + if char not in node.children: + node.children[char] = TriedNode() + node = node.children[char] + node.isEnd = True + + + def search(self, word: str) -> bool: + node = self.root + for char in word: + if char not in node.children: + return False + node = node.children[char] + return node.isEnd + + def startsWith(self, prefix: str) -> bool: + node = self.root + for char in prefix: + if char not in node.children: + return False + node = node.children[char] + 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) diff --git a/word-break/hoyeongkwak.py b/word-break/hoyeongkwak.py new file mode 100644 index 000000000..e1508747d --- /dev/null +++ b/word-break/hoyeongkwak.py @@ -0,0 +1,56 @@ +''' +TriedNode +a : alphabet size +time complexity : O(m) +space complexity : O(m * a) + +dp +time complexity : O(n^2) +space complexity : O(n) +''' +class TriedNode: + def __init__(self): + self.children = {} + self.isEnd = False +class Trie: + def __init__(self): + self.root = TriedNode() + + def insert(self, word): + node = self.root + for char in word: + if char not in node.children: + node.children[char] = TriedNode() + node = node.children[char] + node.isEnd = True + + def search(self, s, start_idx): + node = self.root + endPosition = [] + + for i in range(start_idx, len(s)): + char = s[i] + if char not in node.children: + break + node = node.children[char] + if node.isEnd: + endPosition.append(i + 1) + return endPosition + +class Solution: + def wordBreak(self, s: str, wordDict: List[str]) -> bool: + trie = Trie() + for word in wordDict: + trie.insert(word) + n = len(s) + dp = [False] * (n + 1) + dp[0] = True + + for i in range(n): + if not dp[i]: + continue + endPositions = trie.search(s, i) + + for endPos in endPositions: + dp[endPos] = True + return dp[n] From e52bc1183794531c66613ce1e15d45864e15818d Mon Sep 17 00:00:00 2001 From: hoyeongkwak Date: Sun, 24 Aug 2025 00:02:38 +0900 Subject: [PATCH 2/2] comment modify --- group-anagrams/hoyeongkwak.py | 6 +++--- implement-trie-prefix-tree/hoyeongkwak.py | 6 +++--- word-break/hoyeongkwak.py | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/group-anagrams/hoyeongkwak.py b/group-anagrams/hoyeongkwak.py index 98a38a32f..b53c0a1ca 100644 --- a/group-anagrams/hoyeongkwak.py +++ b/group-anagrams/hoyeongkwak.py @@ -12,9 +12,9 @@ class Solution: def groupAnagrams(self, strs: List[str]) -> List[List[str]]: strResult = {} - for str in strs: - sortedStr = ''.join(sorted(str)) + for word in strs: + sortedStr = ''.join(sorted(word)) if sortedStr not in strResult: strResult[sortedStr] = [] - strResult[sortedStr].append(str) + strResult[sortedStr].append(word) return list(strResult.values()) diff --git a/implement-trie-prefix-tree/hoyeongkwak.py b/implement-trie-prefix-tree/hoyeongkwak.py index bce628bd5..a085e5494 100644 --- a/implement-trie-prefix-tree/hoyeongkwak.py +++ b/implement-trie-prefix-tree/hoyeongkwak.py @@ -12,20 +12,20 @@ space complexity : O(1) ''' -class TriedNode: +class TrieNode: def __init__(self): self.children = {} self.isEnd = False class Trie: def __init__(self): - self.root = TriedNode() + self.root = TrieNode() def insert(self, word: str) -> None: node = self.root for char in word: if char not in node.children: - node.children[char] = TriedNode() + node.children[char] = TrieNode() node = node.children[char] node.isEnd = True diff --git a/word-break/hoyeongkwak.py b/word-break/hoyeongkwak.py index e1508747d..85579227a 100644 --- a/word-break/hoyeongkwak.py +++ b/word-break/hoyeongkwak.py @@ -1,5 +1,5 @@ ''' -TriedNode +TrieNode a : alphabet size time complexity : O(m) space complexity : O(m * a) @@ -8,19 +8,19 @@ time complexity : O(n^2) space complexity : O(n) ''' -class TriedNode: +class TrieNode: def __init__(self): self.children = {} self.isEnd = False class Trie: def __init__(self): - self.root = TriedNode() + self.root = TrieNode() def insert(self, word): node = self.root for char in word: if char not in node.children: - node.children[char] = TriedNode() + node.children[char] = TrieNode() node = node.children[char] node.isEnd = True