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 0000000000..250d08d89f --- /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 0000000000..b53c0a1ca9 --- /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 word in strs: + sortedStr = ''.join(sorted(word)) + if sortedStr not in strResult: + strResult[sortedStr] = [] + strResult[sortedStr].append(word) + 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 0000000000..a085e5494a --- /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 TrieNode: + def __init__(self): + self.children = {} + self.isEnd = False + +class Trie: + def __init__(self): + 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] = TrieNode() + 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 0000000000..85579227a1 --- /dev/null +++ b/word-break/hoyeongkwak.py @@ -0,0 +1,56 @@ +''' +TrieNode +a : alphabet size +time complexity : O(m) +space complexity : O(m * a) + +dp +time complexity : O(n^2) +space complexity : O(n) +''' +class TrieNode: + def __init__(self): + self.children = {} + self.isEnd = False +class Trie: + def __init__(self): + self.root = TrieNode() + + def insert(self, word): + node = self.root + for char in word: + if char not in node.children: + node.children[char] = TrieNode() + 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]