[dolphinflow86] WEEK 11 Solutions - #2849
Conversation
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
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- 패턴: Two Pointers, Greedy, Sort
- 설명: 주어진 코드에서 시작 시간으로 정렬 후 겹치는 구간을 하나의 구간으로 합치는 방식으로 진행되므로 두 포인터로 경계 값을 비교하며(실제 구현은 단일 패스에 가까움) 효율적으로 구간을 병합하는 Greedy 패턴에 해당합니다. 또한 정렬은 문제의 최적 솔루션에 중요한 역할을 합니다.
📊 시간/공간 복잡도 분석
| 복잡도 | |
|---|---|
| Time | O(n log n) |
| Space | O(n) |
피드백: 주어진 구간 배열을 시작점 기준 정렬하고, 겹치면 끝점을 확장합니다. 추가 배열은 필요 없으며, 순회는 한 번만 수행합니다.
개선 제안: 현재 구현이 적절해 보입니다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
📊 dolphinflow86 님의 학습 현황이번 주 제출 문제
누적 학습 요약
문제 풀이 현황
🤖 이 댓글은 GitHub App을 통해 자동으로 작성되었습니다. 🔢 API 사용량 (gpt-5-nano)
|
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
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- 패턴: Hash Map / Hash Set, Greedy
- 설명: 집합에 원소를 저장한 후, 범위 내에서 누락된 값을 선형 탐색하는 방식으로 해결하므로 해시 집합 패턴이 주로 사용되고, 보조적으로 누락 여부를 빠르게 확인하는 탐색이 포함됩니다.
📊 시간/공간 복잡도 분석
| 복잡도 | |
|---|---|
| Time | O(n) |
| Space | O(n) |
피드백: nums의 원소를 집합으로 구성한 뒤 0..n까지 순회하며 빠르게 존재 여부를 검사합니다.
개선 제안: 현재 구현이 적절해 보입니다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
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- 패턴: Two Pointers, Linked List
- 설명: 리스트를 반으로 나누고, 뒤쪽을 역순으로 뒤집은 뒤 두 부분을 교대로 연결하는 방식으로 순서를 재배치한다. 이는 빠른 포인터/느린 포인터로 중간 찾기, 역순 재정렬, 그리고 병합의 3단계로 구성된다.
📊 시간/공간 복잡도 분석
| 복잡도 | |
|---|---|
| Time | O(n) |
| Space | O(1) |
피드백: 세 단계로 나눠 연결 리스트를 in-place로 재배치합니다. 모든 노드에 대해 상수 개의 포인터 작업만 수행합니다.
개선 제안: 현재 구현이 적절해 보입니다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
There was a problem hiding this comment.
깔끔하게 잘 해결하셨네요!
다만 sort에 key는 적용하실 필요가 있으실지 한번 생각해 보시는것도 좋을것 같아요!
There was a problem hiding this comment.
오 넵 짚어주셔서 감사합니다! 그냥 sort만 해도 되겠네요!
반영했습니다.
There was a problem hiding this comment.
해당문제는 사실상 본체가 공간복잡도 O(1)에 해결하는거라 한번 해보시죠!
There was a problem hiding this comment.
감사합니다. 한번 시도 해 보겠습니다!
| if not intervals: | ||
| return [] |
There was a problem hiding this comment.
문제에 1 <= intervals.length <= 104 조건이 있기는 합니다!
There was a problem hiding this comment.
오 넵 따로 early return이 필요없겠네요. 감사합니다!
반영했습니다.
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
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- 패턴: Greedy, Two Pointers, Sorting
- 설명: 간격 배열을 시작점 기준으로 정렬한 뒤, 겹치는 구간을 하나의 구간으로 확장해 합치는 방식으로 최적 해를 구한다. 간단한 탐색으로 이번 구간과 이전 구간의 관계를 판단하며 필요 시 포인터를 이동한다.
📊 시간/공간 복잡도 분석
| 복잡도 | |
|---|---|
| Time | O(n log n) |
| Space | O(n) |
피드백: 입력 간격들을 시작점 기준으로 정렬한 뒤, 현재 구간과 마지막 병합 구간의 끝점을 비교해 필요시 확장한다.
개선 제안: 현재 구현이 적절해 보입니다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
binary-tree-maximum-path-sum/dolphinflow86.py
# 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- 패턴: Depth-First Search, Dynamic Programming
- 설명: 트리의 각 노드를 후위 순회하며 왼쪽/오른쪽 서브트리의 최대 기여도(0 이상)만 이용해 현재 노드를 경유하는 경로의 합을 계산하고, 이를 전역 최댓값으로 갱신한다. 재귀를 이용한 DFS와 부분해를 합쳐 최댓 경로 합을 구하는 DP 패턴이다.
📊 시간/공간 복잡도 분석
| 복잡도 | |
|---|---|
| Time | O(n) |
| Space | O(h) |
피드백: 각 노드에서 좌우 자식의 기여분을 0 이상으로 잘라내고, 현재 노드를 포함한 경로의 합과 전체 최대를 업데이트합니다.
개선 제안: 현재 구현이 적절해 보입니다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
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- 패턴: Breadth-First Search, Graph
- 설명: 정점 간의 인접 리스트를 이용해 BFS로 모든 정점을 방문하며 연결 여부를 확인한다. 간선 수를 먼저 체크하고, 시작 정점에서 차례로 방문하여 트리 조건(모든 노드 연결, 사이클 없음)을 만족하는지 검사한다.
📊 시간/공간 복잡도 분석
| 복잡도 | |
|---|---|
| Time | O(n) |
| Space | O(n) |
피드백: 간선 개수 조건으로 빠르게 실패를 잡고, 인접 리스트를 이용한 BFS로 모든 정점이 방문되는지 확인합니다.
개선 제안: 현재 구현이 적절해 보입니다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
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- 패턴: Depth-First Search, Graph Traversal, Greedy
- 설명: 코드가 간선 수가 n-1인지 간단히 확인한 뒤, DFS로 그래프를 탐색하여 모든 노드에 도달하는지 확인합니다. 그래프 탐색의 대표적 패턴인 DFS를 활용하며, 간선-노드 조건으로 트리 여부를 판단합니다.
📊 시간/공간 복잡도 분석
| 복잡도 | |
|---|---|
| Time | O(n) |
| Space | O(n) |
피드백: 간선이 n-1개이고 모두 연결되면 트리임을 보장하지만, DFS 탐색으로 모든 정점을 방문하는지 확인한다.
개선 제안: 현재 구현이 적절해 보입니다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
답안 제출 문제
작성자 체크 리스트
In Review로 설정해주세요.검토자 체크 리스트
Important
본인 답안 제출 뿐만 아니라 다른 분 PR 하나 이상을 반드시 검토를 해주셔야 합니다!