-
-
Notifications
You must be signed in to change notification settings - Fork 361
[dolphinflow86] WEEK 11 Solutions #2849
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
Changes from all commits
8dd0dd0
8816f2c
7014169
ec6e703
bec2740
b1b13f7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # N is the number of nodes, and H is the height of the binary tree. | ||
| # TC: O(N) - visits each node once in post-order DFS | ||
| # SC: O(H) - recursion call stack proportional to tree height (O(N) in worst case) | ||
|
|
||
| # 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 maxPathSum(self, root) -> int: | ||
| max_sum = float("-inf") | ||
|
|
||
| def max_gain(node) -> int: | ||
| nonlocal max_sum | ||
| if not node: | ||
| return 0 | ||
|
|
||
| left_gain = max(0, max_gain(node.left)) | ||
| right_gain = max(0, max_gain(node.right)) | ||
|
|
||
| current_path = node.val + left_gain + right_gain | ||
| max_sum = max(max_sum, current_path) | ||
|
|
||
| return node.val + max(left_gain, right_gain) | ||
|
|
||
| max_gain(root) | ||
| return max_sum |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석graph-valid-tree/dolphinflow86.py# V is the number of nodes (n), and E is the number of edges.
# TC: O(V + E) - builds adjacency list and traverses graph with BFS
# SC: O(V + E) - stores graph adjacency list and queue/visited set
from collections import deque
class Solution:
def validTree(self, n: int, edges: list[list[int]]) -> bool:
if len(edges) != n - 1:
return False
adj = [[] for _ in range(n)]
for u, v in edges:
adj[u].append(v)
adj[v].append(u)
visited = set([0])
queue = deque([0])
while queue:
node = queue.popleft()
for neighbor in adj[node]:
if neighbor not in visited:
visited.add(neighbor)
queue.append(neighbor)
return len(visited) == n
📊 시간/공간 복잡도 분석
피드백: 간선 개수 조건으로 빠르게 실패를 잡고, 인접 리스트를 이용한 BFS로 모든 정점이 방문되는지 확인합니다. 개선 제안: 현재 구현이 적절해 보입니다.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석graph-valid-tree/dolphinflow86.py# V is the number of nodes (n), and E is the number of edges.
# TC: O(V + E) - builds adjacency list and traverses graph with DFS
# SC: O(V + E) - stores graph adjacency list and stack/visited set
class Solution:
def validTree(self, n: int, edges: list[list[int]]) -> bool:
if len(edges) != n - 1:
return False
adj = [[] for _ in range(n)]
for u, v in edges:
adj[u].append(v)
adj[v].append(u)
visited = set([0])
stack = [0]
while stack:
node = stack.pop()
for neighbor in adj[node]:
if neighbor not in visited:
visited.add(neighbor)
stack.append(neighbor)
return len(visited) == n
📊 시간/공간 복잡도 분석
피드백: 간선이 n-1개이고 모두 연결되면 트리임을 보장하지만, DFS 탐색으로 모든 정점을 방문하는지 확인한다. 개선 제안: 현재 구현이 적절해 보입니다.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| # V is the number of nodes (n), and E is the number of edges. | ||
| # TC: O(V + E) - builds adjacency list and traverses graph with DFS | ||
| # SC: O(V + E) - stores graph adjacency list and stack/visited set | ||
|
|
||
|
|
||
| class Solution: | ||
|
|
||
| def validTree(self, n: int, edges: list[list[int]]) -> bool: | ||
| if len(edges) != n - 1: | ||
| return False | ||
|
|
||
| adj = [[] for _ in range(n)] | ||
| for u, v in edges: | ||
| adj[u].append(v) | ||
| adj[v].append(u) | ||
|
|
||
| visited = set([0]) | ||
| stack = [0] | ||
|
|
||
| while stack: | ||
| node = stack.pop() | ||
| for neighbor in adj[node]: | ||
| if neighbor not in visited: | ||
| visited.add(neighbor) | ||
| stack.append(neighbor) | ||
|
|
||
| return len(visited) == n |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석merge-intervals/dolphinflow86.py# N is the number of intervals.
# TC: O(N log N) - sorts intervals by start time and merges in a single pass
# SC: O(N) - space for the output array and sorting
class Solution:
def merge(self, intervals: list[list[int]]) -> list[list[int]]:
if not intervals:
return []
intervals.sort(key=lambda x: x[0])
merged = [intervals[0]]
for interval in intervals[1:]:
if interval[0] <= merged[-1][1]:
merged[-1][1] = max(merged[-1][1], interval[1])
else:
merged.append(interval)
return merged
📊 시간/공간 복잡도 분석
피드백: 주어진 구간 배열을 시작점 기준 정렬하고, 겹치면 끝점을 확장합니다. 추가 배열은 필요 없으며, 순회는 한 번만 수행합니다. 개선 제안: 현재 구현이 적절해 보입니다.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 깔끔하게 잘 해결하셨네요!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오 넵 짚어주셔서 감사합니다! 그냥 sort만 해도 되겠네요!
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석merge-intervals/dolphinflow86.py# N is the number of intervals.
# TC: O(N log N) - sorts intervals by start time and merges in a single pass
# SC: O(N) - space for the output array and sorting
class Solution:
def merge(self, intervals: list[list[int]]) -> list[list[int]]:
intervals.sort()
merged = [intervals[0]]
for interval in intervals[1:]:
if interval[0] <= merged[-1][1]:
merged[-1][1] = max(merged[-1][1], interval[1])
else:
merged.append(interval)
return merged
📊 시간/공간 복잡도 분석
피드백: 입력 간격들을 시작점 기준으로 정렬한 뒤, 현재 구간과 마지막 병합 구간의 끝점을 비교해 필요시 확장한다. 개선 제안: 현재 구현이 적절해 보입니다.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # N is the number of intervals. | ||
| # TC: O(N log N) - sorts intervals by start time and merges in a single pass | ||
| # SC: O(N) - space for the output array and sorting | ||
|
|
||
|
|
||
| class Solution: | ||
|
|
||
| def merge(self, intervals: list[list[int]]) -> list[list[int]]: | ||
| intervals.sort() | ||
| merged = [intervals[0]] | ||
|
|
||
| for interval in intervals[1:]: | ||
| if interval[0] <= merged[-1][1]: | ||
| merged[-1][1] = max(merged[-1][1], interval[1]) | ||
| else: | ||
| merged.append(interval) | ||
|
|
||
| return merged |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석missing-number/dolphinflow86.py# N is the length of array nums.
# TC: O(N) - stores elements in a hash set and performs O(1) lookups
# SC: O(N) - uses a hash set of size N
class Solution:
def missingNumber(self, nums: list[int]) -> int:
num_set = set(nums)
for i in range(len(nums) + 1):
if i not in num_set:
return i
return -1
📊 시간/공간 복잡도 분석
피드백: nums의 원소를 집합으로 구성한 뒤 0..n까지 순회하며 빠르게 존재 여부를 검사합니다. 개선 제안: 현재 구현이 적절해 보입니다.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 해당문제는 사실상 본체가 공간복잡도 O(1)에 해결하는거라 한번 해보시죠!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 감사합니다. 한번 시도 해 보겠습니다! |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # N is the length of array nums. | ||
| # TC: O(N) - stores elements in a hash set and performs O(1) lookups | ||
| # SC: O(N) - uses a hash set of size N | ||
|
|
||
|
|
||
| class Solution: | ||
|
|
||
| def missingNumber(self, nums: list[int]) -> int: | ||
| num_set = set(nums) | ||
|
|
||
| for i in range(len(nums) + 1): | ||
| if i not in num_set: | ||
| return i | ||
|
|
||
| return -1 |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석reorder-list/dolphinflow86.py# N is the number of nodes in the linked list.
# TC: O(N) - finds middle, reverses second half, and merges in linear time
# SC: O(1) - modifies links in place using constant extra pointers
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reorderList(self, head) -> None:
"""
Do not return anything, modify head in-place instead.
"""
if not head or not head.next or not head.next.next:
return
# 1. Find the middle of the linked list
slow, fast = head, head
while fast.next and fast.next.next:
slow = slow.next
fast = fast.next.next
# 2. Reverse the second half of the list
prev = None
curr = slow.next
slow.next = None
while curr:
next_node = curr.next
curr.next = prev
prev = curr
curr = next_node
# 3. Merge two halves (head and prev)
first, second = head, prev
while second:
tmp1, tmp2 = first.next, second.next
first.next = second
second.next = tmp1
first = tmp1
second = tmp2
📊 시간/공간 복잡도 분석
피드백: 세 단계로 나눠 연결 리스트를 in-place로 재배치합니다. 모든 노드에 대해 상수 개의 포인터 작업만 수행합니다. 개선 제안: 현재 구현이 적절해 보입니다.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 깔끔한 풀이시네여! |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| # N is the number of nodes in the linked list. | ||
| # TC: O(N) - finds middle, reverses second half, and merges in linear time | ||
| # SC: O(1) - modifies links in place using constant extra pointers | ||
|
|
||
| # Definition for singly-linked list. | ||
| # class ListNode: | ||
| # def __init__(self, val=0, next=None): | ||
| # self.val = val | ||
| # self.next = next | ||
|
|
||
|
|
||
| class Solution: | ||
|
|
||
| def reorderList(self, head) -> None: | ||
| """ | ||
| Do not return anything, modify head in-place instead. | ||
| """ | ||
| if not head or not head.next or not head.next.next: | ||
| return | ||
|
|
||
| # 1. Find the middle of the linked list | ||
| slow, fast = head, head | ||
| while fast.next and fast.next.next: | ||
| slow = slow.next | ||
| fast = fast.next.next | ||
|
|
||
| # 2. Reverse the second half of the list | ||
| prev = None | ||
| curr = slow.next | ||
| slow.next = None | ||
|
|
||
| while curr: | ||
| next_node = curr.next | ||
| curr.next = prev | ||
| prev = curr | ||
| curr = next_node | ||
|
|
||
| # 3. Merge two halves (head and prev) | ||
| first, second = head, prev | ||
| while second: | ||
| tmp1, tmp2 = first.next, second.next | ||
| first.next = second | ||
| second.next = tmp1 | ||
| first = tmp1 | ||
| second = tmp2 |
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.
🏷️ 알고리즘 패턴 분석
binary-tree-maximum-path-sum/dolphinflow86.py
📊 시간/공간 복잡도 분석
피드백: 각 노드에서 좌우 자식의 기여분을 0 이상으로 잘라내고, 현재 노드를 포함한 경로의 합과 전체 최대를 업데이트합니다.
개선 제안: 현재 구현이 적절해 보입니다.