Skip to content

[sejineer] Week 04 solutions #1334

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
Apr 26, 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
20 changes: 20 additions & 0 deletions coin-change/sejineer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from collections import deque

class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
queue = deque([(0, 0)])
vis = set()

while queue:
Copy link
Contributor

Choose a reason for hiding this comment

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

저는 처음에 unbounded knapsack 문제로 접근해서 DP로 풀었는데요, 이렇게 최단거리를 구하듯이 BFS로 푸는 것이 더 직관적인 것 같습니다!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

unbounded knapsack으로도 풀 수 있군요! 이 방법도 공부해 보겠습니다 ㅎㅎ

total, count = queue.popleft()
if total == amount:
return count
for coin in coins:
nxt = total + coin
if nxt > amount:
continue
if nxt in vis:
continue
vis.add(nxt)
queue.append((nxt, count + 1))
return -1
15 changes: 15 additions & 0 deletions find-minimum-in-rotated-sorted-array/sejineer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""
시간 복잡도: O(logN)
공간 복잡도: O(1)
"""
class Solution:
def findMin(self, nums: List[int]) -> int:
start, end = 0, len(nums) - 1

while start < end:
mid = (start + end) // 2
if nums[mid] > nums[end]:
start = mid + 1
else:
end = mid
return nums[start]
19 changes: 19 additions & 0 deletions maximum-depth-of-binary-tree/sejineer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""
시간 복잡도: O(N)
공간 복잡도: O(h) h = 트리 높이
"""
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
result = 0

def dfs(tree: Optional[TreeNode], depth: int):
nonlocal result
if tree == None:
Copy link
Contributor

Choose a reason for hiding this comment

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

예전에 파이썬에서 None과 비교할 때 ==를 쓰는 것과 is를 쓰는 것의 차이점을 검색해본 적이 있는데요,

  • ==: 비교하는 객체의 __eq__() 메서드 실행 (➡️ 메서드 오버라이드 시 side effect 발생 가능)
  • is: None 객체와의 reliable 한 비교 가능

이렇게 동작 방식이 달라서 is를 이용해서 None과 비교하는 것을 권장하는 것 같습니다! (물론 알고리즘 인터뷰와 같은 상황이나 대부분의 경우에는 괜찮다고 하네요)

예전에 얻었던 작은 조각 지식 공유드립니다...! 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

오오! 좋은 정보 감사합니다 python에 익숙하지 않아서 적응중인데 이런 작은 정보 하나하나가 소중하네요,, 감사합니다 ㅎㅎ

result = max(result, depth)
return

dfs(tree.left, depth + 1)
dfs(tree.right, depth + 1)

dfs(root, 0)
return result
20 changes: 20 additions & 0 deletions merge-two-sorted-lists/sejineer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""
시간 복잡도: O(n + m)
공간 복잡도: O(1)
"""
class Solution:
def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
node = ListNode(0)
head = node

while list1 and list2:
if list1.val <= list2.val:
head.next = list1
list1 = list1.next
else:
head.next = list2
list2 = list2.next
head = head.next
head.next = list1 if list1 else list2

return node.next
33 changes: 33 additions & 0 deletions word-search/sejineer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""
시간 복잡도: O(N * M * 4^(word_len))
공간 복잡도: O(word_len) 재귀 스택 최대 깊이 word_len
"""
from collections import deque

class Solution:
def exist(self, board: List[List[str]], word: str) -> bool:
n, m = len(board), len(board[0])
word_len = len(word)

def dfs(x: int, y: int, idx: int) -> bool:
if idx == word_len:
return True
if x < 0 or y < 0 or x >= m or y >= n:
return False
if board[y][x] != word[idx]:
return False

tmp, board[y][x] = board[y][x], '#'
Copy link
Contributor

Choose a reason for hiding this comment

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

이렇게 board에 inplace로 방문 표시를 하면 공간 복잡도 측면에서 최적화가 가능하네요!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

원래 있던 board만 사용하는거라 공간 복잡도 측면에서 최적화가 가능할 것 같아요!

for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)):
if dfs(x + dx, y + dy, idx + 1):
return True

board[y][x] = tmp
return False

for i in range(n):
for j in range(m):
if board[i][j] == word[0] and dfs(j, i, 0):
return True

return False