-
Notifications
You must be signed in to change notification settings - Fork 126
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
[haklee] week 10 #536
Merged
Merged
[haklee] week 10 #536
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
더 이상의 자세한 설명은 생략한다.