From 6544db9a9a41550f5a2c8c3cad02c249f35b002d Mon Sep 17 00:00:00 2001 From: siroo Date: Sun, 5 Jan 2025 21:55:05 +0900 Subject: [PATCH 1/3] #221 & #236 solution --- best-time-to-buy-and-sell-stock/jungsiroo.py | 23 ++++++++++ group-anagrams/jungsiroo.py | 44 ++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 best-time-to-buy-and-sell-stock/jungsiroo.py create mode 100644 group-anagrams/jungsiroo.py diff --git a/best-time-to-buy-and-sell-stock/jungsiroo.py b/best-time-to-buy-and-sell-stock/jungsiroo.py new file mode 100644 index 000000000..351db1877 --- /dev/null +++ b/best-time-to-buy-and-sell-stock/jungsiroo.py @@ -0,0 +1,23 @@ +class Solution: + def maxProfit(self, prices: List[int]) -> int: + """ + 가장 수익을 많이 얻을 수 있도록 저점에 매수, 고점에 매도 + 매수와 매도는 서로 다른 날 + + min_price를 빼가면서 price 업데이트 + + Time Complexity : O(n) + Space Complexity : O(1) + """ + + min_price = max(prices) + days = len(prices) + + for day in range(days): + min_price = min(prices[day], min_price) + prices[day] -= min_price + + return max(prices) + + + diff --git a/group-anagrams/jungsiroo.py b/group-anagrams/jungsiroo.py new file mode 100644 index 000000000..a70024778 --- /dev/null +++ b/group-anagrams/jungsiroo.py @@ -0,0 +1,44 @@ +from collections import defaultdict + +class Solution: + def groupAnagrams(self, strs: List[str]) -> List[List[str]]: + # Naive Solution : Sort string + + # 각 단어마다 모두 정렬을 한 뒤 해당 값을 hash로 사용하여 딕셔너리에 추가하는 방법 + # strs[i].length = k + # Time Complexity : O(n*klog(k)) + # Space Complexity : O(n*k) + + """ + + n = len(strs) + word_dict = defaultdict(list) + + for word in strs: + key = hash(''.join(sorted(word))) + word_dict[key].append(word) + + ret = [] + for value in word_dict.values(): + ret.append(value) + return ret + """ + + # Better Solution : Counting + + # anagram 의 특성 중 알파벳 카운트 갯수가 같다는 것을 이용 + # 카운트 갯수를 활용하여 key 값으로 처리 + # Time Complexity : O(n*k) + # Space Complexity : O(n*k) + word_dict = defaultdict(list) + + for word in strs: + freq = [0]*26 + for char in word: + freq[ord(char) - ord('a')] += 1 + word_dict[tuple(freq)].append(word) + + return list(word_dict.values()) + + + From fd2cd7a4334ca86d607ae7bf17e1b81aaf817e4f Mon Sep 17 00:00:00 2001 From: siroo Date: Sun, 5 Jan 2025 23:33:28 +0900 Subject: [PATCH 2/3] word-break solution --- word-break/jungsiroo.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 word-break/jungsiroo.py diff --git a/word-break/jungsiroo.py b/word-break/jungsiroo.py new file mode 100644 index 000000000..5024e3cae --- /dev/null +++ b/word-break/jungsiroo.py @@ -0,0 +1,27 @@ +class Solution: + def wordBreak(self, s: str, wordDict: List[str]) -> bool: + # DP를 활용한 문제 + + """ + KMP나 Rabin Karp를 이용하여 푸는 문제인 줄 알았으나 전혀 아닌 문제 + neetcode의 도움을 받았음 + + 계속 순회를 하면서 if dp[j]를 통해 길이만큼 끊어주고 word_set에 있는지를 확인함 + Time Complexity : O(n^2) + Space Complexity : O(n) + """ + + word_set = set(wordDict) + n = len(s) + + dp = [False] * (n + 1) + dp[0] = True + + for i in range(1, n + 1): + for j in range(i): + if dp[j] and s[j:i] in word_set: + dp[i] = True + break + + return dp[n] + From 3e2c6d92f56a745875afc2cf41a8be209f5c437b Mon Sep 17 00:00:00 2001 From: siroo Date: Mon, 6 Jan 2025 23:59:34 +0900 Subject: [PATCH 3/3] implement trie solution --- implement-trie-prefix-tree/jungsiroo.py | 47 +++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 implement-trie-prefix-tree/jungsiroo.py diff --git a/implement-trie-prefix-tree/jungsiroo.py b/implement-trie-prefix-tree/jungsiroo.py new file mode 100644 index 000000000..fd33a563e --- /dev/null +++ b/implement-trie-prefix-tree/jungsiroo.py @@ -0,0 +1,47 @@ +""" +Recursive vs Iterative + +재귀 방식의 경우, 만약 문자열의 길이가 굉장히 길다면 그만큼의 콜이 일어나고 이는 성능적으로 느려질 수 있음. +두 가지 모두 시간 복잡도 면에서는 O(m) 임 (m = len(string)) + +Node 클래스를 따로 두어 처리하면 가독성 높게 처리할 수 있다. +""" + +class Node: + def __init__(self, key=None): + self.key = key + self.children = {} + self.is_end = False + +class Trie: + def __init__(self): + self.head = Node() + + def insert(self, word: str) -> None: + curr = self.head + + for ch in word: + if ch not in curr.children: + curr.children[ch] = Node(ch) + curr = curr.children[ch] + curr.is_end = True + + def search(self, word: str) -> bool: + curr = self.head + + for ch in word: + if ch not in curr.children: + return False + curr = curr.children[ch] + + return curr.is_end + + def startsWith(self, prefix: str) -> bool: + curr = self.head + + for ch in prefix: + if ch not in curr.children: + return False + curr = curr.children[ch] + return True +