Skip to content

Commit

Permalink
solutions
Browse files Browse the repository at this point in the history
  • Loading branch information
haklee committed Oct 15, 2024
1 parent 3ac0528 commit 5c74619
Show file tree
Hide file tree
Showing 5 changed files with 216 additions and 0 deletions.
31 changes: 31 additions & 0 deletions course-schedule/haklee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""TC: O(node + edge), SC: O(node + edge)
์œ ๋ช…ํ•œ ์œ„์ƒ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ฏ€๋กœ ์„ค๋ช…์€ ์ƒ๋žตํ•œ๋‹ค.
"""


class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
# ์œ„์ƒ ์ •๋ ฌ.

# init
adj_list = [[] for _ in range(numCourses)] # SC: O(edge)
in_deg = [0] * numCourses # SC: O(node)

for edge in prerequisites:
adj_list[edge[0]].append(edge[1])
in_deg[edge[1]] += 1

node_to_search = [i for i, v in enumerate(in_deg) if v == 0] # TC: O(node)
sorted_list = []

# process
while node_to_search:
cur = node_to_search.pop() # TC: ์ตœ์•…์˜ ๊ฒฝ์šฐ ์ด O(node)๋งŒํผ ์‹คํ–‰
sorted_list.append(cur)
for node in adj_list[cur]:
in_deg[node] -= 1 # TC: ์ตœ์•…์˜ ๊ฒฝ์šฐ ์ด O(edge)๋งŒํผ ์‹คํ–‰
if in_deg[node] == 0:
node_to_search.append(node)

return len(sorted_list) == numCourses
32 changes: 32 additions & 0 deletions invert-binary-tree/haklee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""TC: O(n), SC: O(h)
h๋Š” ์ด์ง„ ํŠธ๋ฆฌ์˜ ๋†’์ด.
n์ด ์ „์ฒด ๋…ธ๋“œ ๊ฐœ์ˆ˜๋ผ๊ณ  ํ• ๋•Œ
- ์ตœ์•…์˜ ๊ฒฝ์šฐ ํ•œ ์ชฝ ์ž์‹ ๋…ธ๋“œ๋งŒ ์ฑ„์›Œ์ง. ์ด ๊ฒฝ์šฐ h = n.
- ์ตœ์„ ์˜ ๊ฒฝ์šฐ ์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ. h = log(n).
์•„์ด๋””์–ด:
์–‘์ชฝ ์ž์‹ ๋…ธ๋“œ์— ์ ‘๊ทผํ•ด์„œ ์žฌ๊ท€์ ์œผ๋กœ invert๋ฅผ ์ง„ํ–‰ํ•˜๊ณ , ๋‘ ์ž์‹ ๋…ธ๋“œ๋ฅผ ๋ฐ”๊พผ๋‹ค.
SC:
- ํ˜ธ์ถœ ์Šคํƒ ๊นŠ์ด๋Š” ํŠธ๋ฆฌ์˜ ๊นŠ์ด๊นŒ์ง€ ๊นŠ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, O(h).
TC:
- ๋ชจ๋“  ๋…ธ๋“œ์— ์ ‘๊ทผ. O(n).
"""


# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
def invert(node: Optional[TreeNode]) -> None:
if node is not None:
node.left, node.right = invert(node.right), invert(node.left)
return node

return invert(root)
44 changes: 44 additions & 0 deletions jump-game/haklee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""TC: O(n), SC: O(1)
n์€ ์ฃผ์–ด์ง„ ๋ฆฌ์ŠคํŠธ์˜ ๊ธธ์ด
์•„์ด๋””์–ด:
- ๋์— ์žˆ๋Š” ์•„์ดํ…œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ '์ตœ์†Œ ์–ด๋””๊นŒ์ง€๋Š” ๋„๋‹ฌํ•ด์•ผ ๋ ์นธ๊นŒ์ง€ ์ ํ”„ ๊ฐ€๋Šฅํ•œ์ง€'๋ฅผ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.
- example๋“ค๋กœ ์ดํ•ดํ•ด๋ณด์ž. index๋Š” 0๋ถ€ํ„ฐ ์‹œ์ž‘.
- example 1: [2,3,1,1,4]
- 4๋ฒˆ์งธ ์นธ์— ๋„๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉด ์„ฑ๊ณต์ด๋‹ค. reach_at_least ๊ฐ’์„ 4๋กœ ์ดˆ๊ธฐํ™” ํ•œ๋‹ค.
- 3๋ฒˆ์งธ ์นธ์—์„œ๋Š” ์ตœ๋Œ€ 4๋ฒˆ์งธ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, ์ ์–ด๋„ 3๋ฒˆ ์นธ๊นŒ์ง€ ๊ฐ€๋ฉด ์„ฑ๊ณต์ด๋ฏ€๋กœ
reach_at_least๋ฅผ 3์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.
- 2๋ฒˆ์งธ ์นธ์—์„œ๋Š” ์ตœ๋Œ€ 3๋ฒˆ์งธ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. reach_at_least๋ฅผ 2๋กœ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.
- 1๋ฒˆ์งธ ์นธ์—์„œ๋Š” ์ตœ๋Œ€ 1+3=4๋ฒˆ์งธ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ์ด ์นธ์—์„œ ํ˜„ reach_at_least ๊ฐ’์ธ 2๋ฒˆ์งธ ์นธ๊นŒ์ง€
์ถฉ๋ถ„ํžˆ ๊ฐˆ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ reach_at_least ๊ฐ’์„ 1๋กœ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.
- 0๋ฒˆ์งธ ์นธ์—์„œ๋Š” ์ตœ๋Œ€ 0+2=2๋ฒˆ์งธ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ํ˜„ reach_at_least ๊ฐ’์ธ 1๋ฒˆ์งธ ์นธ๊นŒ์ง€ ์ถฉ๋ถ„ํžˆ
๊ฐˆ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ reach_at_least ๊ฐ’์„ 0์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.
- 0๋ฒˆ์งธ ์นธ์—์„œ ๋ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค.
- example 2: [3,2,1,0,4]
- 4๋ฒˆ์งธ ์นธ์— ๋„๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉด ์„ฑ๊ณต์ด๋‹ค. reach_at_least ๊ฐ’์„ 4๋กœ ์ดˆ๊ธฐํ™” ํ•œ๋‹ค.
- 3๋ฒˆ์งธ ์นธ์—์„œ๋Š” ์ตœ๋Œ€ 3๋ฒˆ์งธ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ํ˜„ reach_at_least ๊ฐ’์ธ 4๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์—†์œผ๋‹ˆ
์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.
- 2๋ฒˆ์งธ ์นธ์—์„œ๋Š” ์ตœ๋Œ€ 2+1=3๋ฒˆ์งธ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋„ ํ˜„ reach_at_least ๊ฐ’์ธ 4๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์—†๊ณ ,
์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.
- 1๋ฒˆ์งธ ์นธ์—์„œ๋Š” ์ตœ๋Œ€ 1+2=3๋ฒˆ์งธ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ๋น„์Šทํ•˜๊ฒŒ ์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.
- 0๋ฒˆ์งธ ์นธ์—์„œ๋Š” ์ตœ๋Œ€ 0+3=3๋ฒˆ์งธ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ๋น„์Šทํ•˜๊ฒŒ ์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.
- reach_at_least ๊ฐ’์ด 0์ด ์•„๋‹ˆ๋‹ค. ์ฆ‰, 0๋ฒˆ์งธ ์นธ์—์„œ๋Š” ๋ ์นธ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์—†๋‹ค.
SC:
- reach_at_least ๊ฐ’์— ์ธ๋ฑ์Šค ํ•˜๋‚˜๋งŒ ๊ด€๋ฆฌํ•œ๋‹ค. ์ฆ‰, O(1).
TC:
- nums์˜ ๋์—์„œ ๋‘ ๋ฒˆ์งธ ์•„์ดํ…œ๋ถ€ํ„ฐ ์ฒซ ๋ฒˆ์งธ ์•„์ดํ…œ๊นŒ์ง€ ์ˆœ์ฐจ์ ์œผ๋กœ ์ ‘๊ทผํ•˜๋ฉด์„œ reach_at_least๊ฐ’์„ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค. O(n).
"""


class Solution:
def canJump(self, nums: List[int]) -> bool:
reach_at_least = len(nums) - 1

for i in range(len(nums) - 2, -1, -1):
if nums[i] + i >= reach_at_least:
reach_at_least = i

return reach_at_least == 0
56 changes: 56 additions & 0 deletions merge-k-sorted-lists/haklee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""TC: O(n*log(l)), SC: O(l)
l์€ ๋ฆฌ์ŠคํŠธ ๊ฐœ์ˆ˜, n์€ ์ „์ฒด ์•„์ดํ…œ ๊ฐœ์ˆ˜
์•„์ด๋””์–ด:
- ๊ฐ ๋ฆฌ์ŠคํŠธ์—์„œ ์ œ์ผ ์•ž์— ์žˆ๋Š” ๊ฐ’์„ ๋ฝ‘์•„์„œ ์šฐ์„ ์ˆœ์œ„ ํ์— ๋„ฃ๋Š”๋‹ค.
- ์šฐ์„ ์ˆœ์œ„ ํ์˜ ์ œ์ผ ์•ž์— ์žˆ๋Š” ๊ฐ’์„ ๋ฝ‘์•„์„œ
- ์ด ๊ฐ’์ด ์–ด๋Š ๋ฆฌ์ŠคํŠธ์—์„œ ๋‚˜์™”๋Š”์ง€ ํ™•์ธํ•ด์„œ ํ•ด๋‹น ๋ฆฌ์ŠคํŠธ์˜ ์ œ์ผ ์•ž์— ์žˆ๋Š” ๊ฐ’์„ ์ƒˆ๋กœ ๋ฝ‘์•„์„œ ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ์ฑ„์šด๋‹ค.
- ์šฐ์„ ์ˆœ์œ„ ํ์—์„œ ๋ฝ‘์€ ๊ฐ’์€ ๊ฒฐ๊ณผ ๋ฆฌ์ŠคํŠธ์— ๋”ํ•œ๋‹ค.
SC:
- ์šฐ์„ ์ˆœ์œ„ ํ์— ์ตœ๋Œ€ list์˜ ๊ฐœ์ˆ˜ ๋งŒํผ์˜ ์•„์ดํ…œ ์กด์žฌ ๊ฐ€๋Šฅ. O(l).
-
TC:
- heap ํฌ๊ธฐ๋Š” ์ตœ๋Œ€ l์ด๋‹ค.
- ์ด heap์— ์•„์ดํ…œ์„ pushํ•˜๊ณ  popํ• ๋•Œ O(log(l)) ์‹œ๊ฐ„ ์†Œ์š”.
- ์œ„์˜ ์‹œํ–‰์„ ์ „์ฒด ์•„์ดํ…œ ๊ฐœ์ˆ˜ ๋งŒํผ ํ•œ๋‹ค.
- ์ข…ํ•ฉํ•˜๋ฉด O(n*log(l))
"""

# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next

from heapq import heappush, heappop


class Solution:
def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
heap = []
head = ListNode()
tail = head

# init
for i in range(len(lists)):
if lists[i]:
heappush(heap, (lists[i].val, i))
lists[i] = lists[i].next

# process
while heap:
v, idx = heappop(heap)

# heap ๋‹ค์‹œ ์ฑ„์›Œ๋„ฃ๊ธฐ
if lists[idx]:
heappush(heap, (lists[idx].val, idx))
lists[idx] = lists[idx].next

# ๊ฒฐ๊ณผ๋ฌผ ์ฑ„์›Œ๋„ฃ๊ธฐ
tail.next = ListNode(v)
tail = tail.next

return head.next
53 changes: 53 additions & 0 deletions search-in-rotated-sorted-array/haklee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""TC: O(n), SC: O(1)
n์€ ์ฃผ์–ด์ง„ ๋ฆฌ์ŠคํŠธ์˜ ๊ธธ์ด.
์•„์ด๋””์–ด:
- Rotated Sorted Array๋Š” ํŠน์„ฑ์ƒ `๊ฐ’์ด ์ฆ๊ฐ€ํ•˜๋‹ค๊ฐ€ -> ๊ฐ‘์ž๊ธฐ ๊ฐ’์ด ํ•œ ๋ฒˆ ๊ฐ์†Œ -> ์ดํ›„ ๋‹ค์‹œ ์ญ‰ ์ฆ๊ฐ€`ํ•œ๋‹ค.
- ์œ„์˜ ๊ด€์ฐฐ์— ๋”ฐ๋ฅด๋ฉด ๊ฐ’์ด ๊ฐ์†Œํ•˜๋Š” `์ ˆ์ `์€ ์ตœ๋Œ€ ํ•œ ๊ตฐ๋ฐ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค.
- rotate ์‹œํ–‰์„ 0๋ฒˆ ํ•œ ๊ฒฝ์šฐ ์ ˆ์ ์ด ์—†์Œ. ๊ทธ ์™ธ์—๋Š” ์ ˆ์ ์ด ํ•œ ๋ฒˆ ์ƒ๊น€.
- ์ฆ‰, ๋ฆฌ์ŠคํŠธ์—์„œ ๋‘ ๊ตฌ๊ฐ„์„ ๊ฒน์น˜์ง€ ์•Š๊ฒŒ ์žก์œผ๋ฉด ์ด ๋‘ ๊ตฌ๊ฐ„ ์ค‘ ์ ์–ด๋„ ํ•œ ๊ตฌ๊ฐ„์€ ascending order๊ฐ€ ๋ณด์žฅ๋œ๋‹ค.
- ascendingํ•˜๋Š” ๊ตฌ๊ฐ„์— ์ฐพ๊ณ ์ž ํ•˜๋Š” ๊ฐ’์ด ์žˆ๋Š”์ง€ ํŒ๋ณ„ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ binary search์™€ ๋น„์Šทํ•œ ๋ฐฉ์‹์œผ๋กœ search ๊ฐ€๋Šฅ.
- ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ฝ”๋“œ๋ฅผ ์ฐธ์กฐํ•˜๋ฉด ๋œ๋‹ค.
SC:
- binary search์™€ ๋น„์Šทํ•˜๊ฒŒ, ํƒ์ƒ‰ ๊ตฌ๊ฐ„์˜ ์‹œ์ž‘, ๋, ์ค‘๊ฐ„ ์ธ๋ฑ์Šค๋ฅผ ๊ด€๋ฆฌ. O(1).
TC:
- binary search์™€ ๋น„์Šทํ•˜๊ฒŒ ๊ตฌ๊ฐ„์ด ๊ณ„์† ์ ˆ๋ฐ˜ ํฌ๊ธฐ๋กœ ์ค„์–ด๋“ ๋‹ค. O(log(n)).
"""


class Solution:
def search(self, nums: List[int], target: int) -> int:
s, e = 0, len(nums) - 1
while s < e:
m = (s + e) // 2

# ์ ˆ์ ์€ ํ•˜๋‚˜๋‹ค. [s, m]๊ณผ [m+1, e]๊ตฌ๊ฐ„ ์ค‘ ํ•œ ๊ณณ์— ์ ˆ์ ์กด์žฌ.
# ์ ˆ์ ์ด ์—†๋Š” ๊ตฌ๊ฐ„์€ ascending order๊ฐ€ ๋ณด์žฅ๋˜๋ฏ€๋กœ,
# ์ด ๊ตฌ๊ฐ„์— target์ด ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋กœ ๋‘˜ ์ค‘ ํ•œ ๊ตฌ๊ฐ„์„ ํƒ์ƒ‰ ๊ตฌ๊ฐ„์—์„œ ์ œ์™ธํ•œ๋‹ค.
if nums[s] < nums[m]:
# [s, m] ๊ตฌ๊ฐ„์ด ascending order.
if (nums[s] > target and nums[m] > target) or (
nums[s] < target and nums[m] < target
):
# nums[s]์™€ nums[m]์ด target๋ณด๋‹ค ๋‘˜ ๋‹ค ํฌ๊ฑฐ๋‚˜ ๋‘˜ ๋‹ค ์ž‘์œผ๋ฉด
# [m + 1, e] ๊ตฌ๊ฐ„์—์„œ ํƒ์ƒ‰์„ ์ด์–ด๊ฐ„๋‹ค.
s = m + 1
else:
# ์•„๋‹ˆ๋ฉด [s, m] ๊ตฌ๊ฐ„์—์„œ ํƒ์ƒ‰์„ ์ด์–ด๊ฐ„๋‹ค.
e = m
else:
# [m + 1, e] ๊ตฌ๊ฐ„์ด ascending order.
if (nums[m + 1] > target and nums[e] > target) or (
nums[m + 1] < target and nums[e] < target
):
# nums[m + 1]๊ณผ nums[e]๊ฐ€ target๋ณด๋‹ค ๋‘˜ ๋‹ค ํฌ๊ฑฐ๋‚˜ ๋‘˜ ๋‹ค ์ž‘์œผ๋ฉด
# [s, m] ๊ตฌ๊ฐ„์—์„œ ํƒ์ƒ‰์„ ์ด์–ด๊ฐ„๋‹ค.
e = m
else:
# ์•„๋‹ˆ๋ฉด [m + 1, e] ๊ตฌ๊ฐ„์—์„œ ํƒ์ƒ‰์„ ์ด์–ด๊ฐ„๋‹ค.
s = m + 1

return s if nums[s] == target else -1

0 comments on commit 5c74619

Please sign in to comment.