diff --git a/best-time-to-buy-and-sell-stock/KwonNayeon.py b/best-time-to-buy-and-sell-stock/KwonNayeon.py new file mode 100644 index 000000000..5fc4f4564 --- /dev/null +++ b/best-time-to-buy-and-sell-stock/KwonNayeon.py @@ -0,0 +1,30 @@ +""" +Constraints: +1. 1 <= prices.length <= 10^5 +2. 0 <= prices[i] <= 10^4 + +Time Complexity: O(n) + +Space Complexity: O(1) + +풀이 방법: +- 배열을 한 번 순회하면서: + 1. 현재까지의 최소 가격(min_price)을 계속 갱신 + 2. 현재 가격에서 최소 가격을 뺀 값(현재 가능한 이익)과 기존 최대 이익을 비교하여 더 큰 값을 저장 +- 이 방식으로 각 시점에서 가능한 최대 이익을 계산함 + +To Do: +- 다른 접근 방법 찾아보기 (Two Pointers, Dynamic Programming) +""" + +class Solution: + def maxProfit(self, prices: List[int]) -> int: + min_price = prices[0] + max_profit = 0 + + for i in range(1, len(prices)): + min_price = min(min_price, prices[i]) + max_profit = max(max_profit, prices[i] - min_price) + + return max_profit + diff --git a/encode-and-decode-strings/KwonNayeon.py b/encode-and-decode-strings/KwonNayeon.py new file mode 100644 index 000000000..57d61b29b --- /dev/null +++ b/encode-and-decode-strings/KwonNayeon.py @@ -0,0 +1,44 @@ +""" +Constraints: +1. 0 <= strs.length <= 200 +2. 0 <= strs[i].length <= 200 +3. strs[i]는 유니코드 문자들로만 구성됨 +4. encode된 string은 반드시 decode 가능해야 함 + +Time Complexity: O(n) + +Space Complexity: O(n) + +풀이방법: +- encode: 각 문자열 뒤에 '#' 추가하여 하나로 합침 +- decode: '#'을 기준으로 문자열 분할 + +Further consideration: +- 현재 방식은 입력 문자열에 '#'이 포함된 경우 문제 발생 가능 +- 개선 방법: 문자열 길이 + 구분자 + 문자열 형식 사용 + 예: ["Hello", "World"] -> "5#Hello5#World" +""" + +class Solution: + """ + @param: strs: a list of strings + @return: encodes a list of strings to a single string. + Examples: + input: ["Hello", "World"] + output: "Hello#World" + """ + def encode(self, strs): + result = "" + for s in strs: + result = result + s + "#" + return result[:-1] + + """ + @param: str: A string + @return: decodes a single string to a list of strings + Examples: + input: "Hello#World" + output: ["Hello", "World"] + """ + def decode(self, str): + return str.split("#") diff --git a/group-anagrams/KwonNayeon.py b/group-anagrams/KwonNayeon.py new file mode 100644 index 000000000..531a28b04 --- /dev/null +++ b/group-anagrams/KwonNayeon.py @@ -0,0 +1,32 @@ +""" +Constraints: +1. 1 <= strs.length <= 10^4 +2. 0 <= strs[i].length <= 100 +3. strs[i] consists of lowercase English letters. + +Time Complexity: O(N * K * log K) +- N은 입력 문자열의 개수 (strs의 길이) +- K는 가장 긴 문자열의 길이 +- 각 문자열을 정렬하는데 K * log K가 필요하고 +- 이걸 N개의 문자열에 대해 수행 + +Space Complexity: O(N * K) +- N개의 문자열을 저장해야 함 +- 각 문자열의 길이는 최대 K +- anagram_dict에 모든 문자열을 저장하기 때문 +""" + +class Solution: + def groupAnagrams(self, strs: List[str]) -> List[List[str]]: + anagram_dict = {} + + for s in strs: + sorted_str = ''.join(sorted(s)) + + if sorted_str in anagram_dict: + anagram_dict[sorted_str].append(s) + else: + anagram_dict[sorted_str] = [s] + + return list(anagram_dict.values()) + diff --git a/implement-trie-prefix-tree/KwonNayeon.py b/implement-trie-prefix-tree/KwonNayeon.py new file mode 100644 index 000000000..ec589a830 --- /dev/null +++ b/implement-trie-prefix-tree/KwonNayeon.py @@ -0,0 +1,89 @@ +""" +Constraints: +1. 1 <= word.length, prefix.length <= 2000 +2. word and prefix consist only of lowercase English letters. +3. At most 3 * 10^4 calls in total will be made to insert, search, and startsWith. + +Time Complexity: +- insert: O(m), m은 입력 단어의 길이 +- search: O(m), m은 검색 단어의 길이 +- startsWith: O(m), m은 접두사의 길이 + +Space Complexity: +- O(N*M), N은 저장된 단어의 개수, M은 평균 단어 길이 + +이해한 내용: +1. Prefix(접두사)의 의미 + - 문법적 접두사(un-, pre- 등)가 아님 + - 단순히 단어의 앞부분에 있는 문자열을 의미 + - 예: "apple"의 접두사 -> "a", "ap", "app", "appl", "apple" + +2. 실행 방식 + - 입력으로 주어진 명령어를 순차적으로 실행 + - 예: ["Trie", "insert", "search"] 순서대로 실행 + - 각 명령어에 해당하는 인자값도 순서대로 적용 + +3. 자료구조 선택 (Trie with Hash Table) + - Trie의 각 노드에서 자식 노드를 저장할 때 해시 테이블 사용 + - 키: 다음 문자, 값: 해당 문자의 TrieNode + - 장점: 다음 문자 검색이 O(1)로 가능 + +Notes: +- 혼자 구현하기 어려워서, 공부한 내용을 정리만 했습니다. +""" + +# 트리의 각 "노드(마디)"를 표현하는 클래스 +class TrieNode: + def __init__(self): + # children은 "다음 글자들을 저장하는 공간" + # 예: 'a' 다음에 'p'가 올 수 있다면 children['p']에 저장 + self.children = {} + + # is_end는 "여기까지가 하나의 단어가 되는지"를 표시 + # 예: "app"을 저장했다면, p노드의 is_end가 True + self.is_end = False + +# 트리 전체를 관리하는 클래스 +class Trie: + def __init__(self): + # 트리의 시작점 생성 + # 실제 글자들은 root 밑에서부터 시작 + 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.is_end = True + + # 단어가 트리에 있는지 찾는 함수 + def search(self, word: str) -> bool: + node = self.root + for char in word: + if char in node.children: + node = node.children[char] + else: + return False + return node.is_end + + # 해당 접두사로 시작하는 단어가 있는지 확인하는 함수 + def startsWith(self, prefix: str) -> bool: + node = self.root + for char in prefix: + if char in node.children: + node = node.children[char] + else: + return False + return True + +""" +사용 예시: +trie = Trie() +trie.insert("apple") # "apple" 저장 +trie.search("apple") # True 반환 (apple이 있음) +trie.search("app") # False 반환 (app은 없음) +trie.startsWith("app") # True 반환 (app으로 시작하는 단어가 있음) +"""