Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[KwonNayeon] Week 5 #853

Merged
merged 9 commits into from
Jan 12, 2025
Merged
30 changes: 30 additions & 0 deletions best-time-to-buy-and-sell-stock/KwonNayeon.py
Original file line number Diff line number Diff line change
@@ -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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다른 접근 방법(Two Pointers, Dynamic Programming)을 고려해 보라고 주석에 적혀 있는데, 이 코드와 비교했을 때 어떤 장단점이 있을까요?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lledellebell 제약조건이 추가되었을 때를 고려해볼 수 있을 것 같습니다.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@EgonD3V 조금 늦었지만, 답변 감사합니다!

"""

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

44 changes: 44 additions & 0 deletions encode-and-decode-strings/KwonNayeon.py
Original file line number Diff line number Diff line change
@@ -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 + "#"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"#"같은 클래스의 다른 메서드에서도 사용하는 변수는 클래스 변수로 선언하고 사용하면 좋을 것 같습니다.

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("#")
32 changes: 32 additions & 0 deletions group-anagrams/KwonNayeon.py
Original file line number Diff line number Diff line change
@@ -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]
Comment on lines +26 to +29
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if sorted_str in anagram_dict:
anagram_dict[sorted_str].append(s)
else:
anagram_dict[sorted_str] = [s]
anagram_dict[sorted_str] = anagram_dict.get(sorted_str, []) + [s]

dict의 기본 내장 메서드를 이렇게 사용할 수도 있습니다

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리뷰 감사합니다! @EgonD3V 님 덕분에 조건문 없이 깔끔하게 코드를 구현하는 법을 배웠어요!


return list(anagram_dict.values())

89 changes: 89 additions & 0 deletions implement-trie-prefix-tree/KwonNayeon.py
Original file line number Diff line number Diff line change
@@ -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
Comment on lines +37 to +44
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TreeNode가 직접 값을 들고 있지 않고 children의 key로만 들고 있으면 나중에 Trie의 다른 조건이 포함된 조회 관련 메서드를 구현할 때 불편할 것 같습니다.


# 트리 전체를 관리하는 클래스
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으로 시작하는 단어가 있음)
"""
Loading