Skip to content

[yyyyyyyyyKim] WEEK 05 solutions #1386

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

Merged
merged 5 commits into from
May 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions best-time-to-buy-and-sell-stock/yyyyyyyyyKim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class Solution:
def maxProfit(self, prices: List[int]) -> int:
buy = 10001
profit = 0

for i in range(len(prices)):
if prices[i] < buy:
buy = prices[i]

if prices[i] - buy > profit:
profit = prices[i] - buy
Copy link
Contributor

Choose a reason for hiding this comment

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

buy의 경우에는 buy = min(buy, prices[i])으로, profit의 경우에는 profit = max(profit, prices[i] - buy)로 업데이트한다면 if 문을 삭제해 코드 라인 수를 더 줄일 수 있을 것 같아요!

또한 for loop 내에서 인덱스 i를 사용하지 않고 prices[i]만 사용하기 때문에, for price in prices로 순회할 수도 있을 것 같습니다 😄


return profit
37 changes: 37 additions & 0 deletions encode-and-decode-strings/yyyyyyyyyKim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
class Solution:
"""
@param: strs: a list of strings
@return: encodes a list of strings to a single string.
"""
def encode(self, strs):
# write your code here
answer = ""

# 문자열 앞에 "문자열길이 + :" 붙여서 인코딩
for i in strs:
answer += str(len(i)) + ":" + i

return answer

"""
@param: str: A string
@return: decodes a single string to a list of strings
"""
def decode(self, s): # 변수명str을 s로 수정
# write your code here
answer = []
i = 0

# ":"를 기준으로 앞에 숫자(문자열길이)만큼 끊어서 디코딩
while i < len(s):
j = i

# 문자열길이가 한자리 이상일 수 있으니까 ":"를 기준으로 함
while s[j] != ":":
j += 1

length = int(s[i:j]) # 문자열의 길이 추출
answer.append(s[j+1:j+1+length]) # 길이만큼 문자열 추출해서 answer에 넣기
i = j + 1 + length # 잘라진 문자열 뒤로 이동

return answer
17 changes: 17 additions & 0 deletions group-anagrams/yyyyyyyyyKim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:

# 딕셔너리
answer = {}

for i in strs:
key = ''.join(sorted(i)) # 정렬해서 키 만들기

# answer에 키가 없으면 키 추가
if key not in answer:
answer[key] = []
Copy link
Contributor

Choose a reason for hiding this comment

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

이렇게 하면 defaultdict를 사용하지 않고도 없는 key 처리를 깔끔하게 할 수가 있군요! 배워갑니다 🤩


answer[key].append(i) # key에 단어 추가

# list로 변환해서 리턴
return list(answer.values())
67 changes: 67 additions & 0 deletions implement-trie-prefix-tree/yyyyyyyyyKim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""
TrieNode: 한 글자를 담는 노드
- children: 자식노드들 저장하는 딕셔너리
- end: 해당 노드에서 단어가 끝나는지 여부
"""
class TrieNode:
# Trie 노드 초기화
def __init__(self):
self.children = {} # 자식 노드 저장
self.end = False # 단어의 끝인지 표시

"""
Trie(트라): Tree기반의 자료구조(Tree자료구조중하나), 문자열 검색을 위한 특수한 Tree 자료구조
- insert: 주어진 word 삽입
- search: 주어진 word가 Trie에 있는지 검색
- startwith: 주어진 prefix로 시작하는 단어가 있는지 확인
"""
class Trie:
# Trie 자료구조 초기화(루트 노드 생성)
def __init__(self):
# Trie의 시작(빈 루트 노드 생성)
self.root = TrieNode()

def insert(self, word: str) -> None:
node = self.root # 단어 삽입의 시작 위치 = 루트 노드

# 단어의 글자 하나하나를 Trie에 삽입
for i in word:
# 글자가 자식 노드에 없으면 새로운 노드 생성해서 뻗어가기
if i not in node.children:
node.children[i] = TrieNode()

node = node.children[i] # 다음 글자(노드)로 이동

node.end = True # 단어 삽입 완료, 현재 노드에서 단어의 끝 표시(True)

def search(self, word: str) -> bool:
node = self.root

for i in word:
# 글자가 자식노드에 존재하지 않으면 False 리턴
if i not in node.children:
return False

node = node.children[i] # 다음 글자(노드)로 이동

# 단어를 다 돌고 마지막 노드가 단어의 끝이면 node.end는 True
return node.end

def startsWith(self, prefix: str) -> bool:
node = self.root

for i in prefix:
# 글자가 자식노드에 존재하지 않으면 False 리턴
if i not in node.children:
return False

node = node.children[i] # 다음 글자(노드)로 이동

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)
16 changes: 16 additions & 0 deletions word-break/yyyyyyyyyKim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:

# DP
dp = [False]*(len(s)+1)
dp[0] = True # 빈문자열은 단어없이도 만들 수 있음(True)

# i : s의 i번째 문자
for i in range(1,len(s)+1):
# j : 단어 자르는 시작위치. s[:j]가 wordDict에 있고, s[j:i]가 wordDict에 있는지 확인.
for j in range(i):
if dp[j] and s[j:i] in wordDict:
Copy link
Contributor

Choose a reason for hiding this comment

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

저도 처음에 yyyyyyyyyKim님과 유사하게 풀이했으나 솔루션을 참고하고 나서 두 가지 관점에서 시간 복잡도를 더 최적화할 수 있다는 걸 알게되었는데요, 혹시나 도움이 되실까하여 공유드립니다~!


  1. str in wordDict: in으로 조회하는 시간 복잡도를 O(n) ➡️ O(1) 최적화

    • wordDictlist이기 때문에 strin으로 찾을 때 순차적으로 찾게되어 시간 복잡도가 O(n)이 됩니다.
    • wordDict에서 strin으로 찾을 때 O(1)에 찾으려면 wordDictset으로 만들면 됩니다.
  2. s[j:i] in wordDict: s[j:i] 문자열 슬라이싱을 trie로 대체하여 시간 복잡도를 O(n) ➡️ O(1) 최적화

    • str in wordDict를 O(1)으로 줄였어도, strs[j:i]와 같이 문자열 슬라이싱으로 만들면 O(n)이 소요되게 됩니다.
    • Implement Trie Prefix Tree #256 문제에서 사용하셨던 trie 자료구조를 이용하면, trie를 타고 내려가면서 매 루프마다 가장 끝 문자만 확인하면 되기 때문에 O(1)로 최적화할 수 있습니다.

dp[i] = True # s[i]까지 자를 수 있음(True)
break # 자를 수 있으니까 더 볼 필요 없음

return dp[len(s)]