[yuseok89] WEEK 07 Solutions - #2800
Conversation
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
container-with-most-water/yuseok89.py
# TC: O(N)
# SC: O(1)
class Solution:
def maxArea(self, height: List[int]) -> int:
l = 0
r = len(height) - 1
max_height = max(height)
ans = 0
while l < r:
ans = max(ans, min(height[l], height[r]) * (r - l))
if ans > max_height * (r - l):
return ans
if height[l] < height[r]:
l += 1
else:
r -= 1
return ans
- 패턴: Two Pointers, Greedy
- 설명: 두 포인터를 양 끝에서 시작해 유효 용량을 계산하고, 더 작은 벽 높이에 맞춰 한쪽을 이동시키며 최댓값을 갱신하는 방식으로 최적해를 찾습니다. 또한 각 단계에서 현재 해와 후보 해를 비교해 더 좋은 방향으로 이동하는 점에서 Greedy 특성을 보입니다.
📊 시간/공간 복잡도 분석
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(N) | O(n) | ✅ |
| Space | O(1) | O(1) | ✅ |
피드백: 가장 큰 면적을 찾기 위해 양 끝에서 좁혀가며 후보 면적을 갱신한다. 최적해는 반드시 한 포인터이동으로 도달한다.
개선 제안: 현재 구현이 적절해 보입니다.
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
design-add-and-search-words-data-structure/yuseok89.py
class WordDictionary:
def __init__(self):
self.trie = {}
def addWord(self, word: str) -> None:
cur = self.trie
for c in word:
if c not in cur:
cur[c] = {}
cur = cur[c]
cur[0] = True
def search(self, word: str) -> bool:
n = len(word)
def rec(cur: dict, idx: int) -> bool:
if idx == n:
return 0 in cur
if word[idx] == '.':
for next in cur:
if next == 0:
continue
if rec(cur[next], idx + 1):
return True
return False
else:
if word[idx] in cur:
return rec(cur[word[idx]], idx + 1)
else:
return False
return rec(self.trie, 0)
- 패턴: Trie, Hash Map / Hash Set, Backtracking
- 설명: 트라이(Trie) 구조로 단어를 저장하고 검색하며, '.' 와일드카드를 재귀적으로 탐색하는 방식이 핵심이다. 부분적으로 탐색 공간 확장을 위한 백트래킹 성격의 재귀가 사용된다.
📊 시간/공간 복잡도 분석
ℹ️ 이 파일에는 2가지 풀이가 포함되어 있어 각각 분석합니다.
풀이 1: WordDictionary.addWord — Time: O(len(word)) / Space: O(total_nodes)
| 복잡도 | |
|---|---|
| Time | O(len(word)) |
| Space | O(total_nodes) |
피드백: 트라이 기반으로 단어를 삽입하고 와일드카드 검색까지 재귀적으로 처리한다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 2: WordDictionary.search — Time: O(len(word) * branching) / Space: O(depth)
| 복잡도 | |
|---|---|
| Time | O(len(word) * branching) |
| Space | O(depth) |
피드백: '.'가 다수일 때 탐색 공간이 증가하므로 최악의 경우 지수적으로 증가할 수 있다.
개선 제안: 현재 구현이 적절해 보입니다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
longest-increasing-subsequence/yuseok89.py
# TC: O(NlogN)
# SC: O(N)
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
arr = []
for num in nums:
if len(arr) == 0 or arr[-1] < num:
arr.append(num)
else:
idx = bisect_left(arr, num)
arr[idx] = num
return len(arr)
- 패턴: Binary Search, Dynamic Programming
- 설명: 최적 증가 수열 길이는 이진 탐색으로 부분수열의 마지막 원소를 갱신하는 방식으로 구해지며, DP의 최적화와 이진 탐색의 결합으로 해결한다.
📊 시간/공간 복잡도 분석
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(NlogN) | O(n log n) | ✅ |
| Space | O(N) | O(n) | ✅ |
피드백: 이분 탐색 기반 최적화로 LIS를 효율적으로 얻는다.
개선 제안: 현재 구현이 적절해 보입니다.
📊 yuseok89 님의 학습 현황이번 주 제출 문제
누적 학습 요약
문제 풀이 현황
🤖 이 댓글은 GitHub App을 통해 자동으로 작성되었습니다. 🔢 API 사용량 (gpt-5-nano)
|
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
longest-substring-without-repeating-characters/yuseok89.py
# TC: O(N)
# SC: O(1)
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
seen = set()
ans = 0
l, r = 0, 0
for r in range(0, len(s)):
c = s[r]
while c in seen:
seen.remove(s[l])
l += 1
seen.add(c)
ans = max(ans, r - l + 1)
return ans
- 패턴: Sliding Window
- 설명: 두 포인터(l, r)로 윈도우를 확장/축소하며 중복 문자를 제거하는 방식으로 부분문자열의 길이를 구한다. 해시셋으로 현재 윈도우의 문자를 관리한다.
📊 시간/공간 복잡도 분석
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(N) | O(n) | ✅ |
| Space | O(1) | O(k) | ❌ |
피드백: 한 방향으로 윈도우를 이동시키며 중복을 제거한다.
개선 제안: 현재 구현이 적절해 보입니다.
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
number-of-islands/yuseok89.py
# TC: O(NM)
# SC: O(NM)
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
ans = 0
n = len(grid)
m = len(grid[0])
dirs = [[-1, 0], [1, 0], [0, -1], [0, 1]]
def fill(row: int, col: int):
grid[row][col] = '0'
for dir in dirs:
new_row = row + dir[0]
new_col = col + dir[1]
if 0 <= new_row < n and 0 <= new_col < m and grid[new_row][new_col] == '1':
fill(new_row, new_col)
for i in range(0, n):
for j in range(0, m):
if grid[i][j] == '1':
fill(i, j)
ans += 1
return ans
- 패턴: Depth-First Search, Hash Map / Hash Set
- 설명: 섬의 연결 여부를 재귀적으로 탐색하며 인접한 땅을 방문 처리합니다. 재귀로 인접 칸을 탐색하는 DFS 방식이 핵심이며, 방문 여부를 그래드(grid) 값을 바꿔 표시합니다.
📊 시간/공간 복잡도 분석
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(NM) | O(n*m) | ❌ |
| Space | O(NM) | O(n*m) | ❌ |
피드백: 모든 셀을 한 번씩 방문하고 인접하던 땅을 탐색한다.
개선 제안: 현재 구현이 적절해 보입니다.
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
reverse-linked-list/yuseok89.py
# TC: O(N)
# SC: O(1)
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
prev = None
cur = head
while cur:
next = cur.next
cur.next = prev
prev = cur
cur = next
return prev
- 패턴: Two Pointers, Linked List
- 설명: 해당 코드는 한 노드를 지나며 포인터 두 개를 사용해 연결 리스트를 역순으로 뒤집는다. 각 노드를 방문하며 앞의 포인터를 차례로 뒤로 보냄으로써 제자리에서 역전하는 패턴이다.
📊 시간/공간 복잡도 분석
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(N) | O(n) | ✅ |
| Space | O(1) | O(1) | ✅ |
피드백: 중간 포인터를 이용해 순서를 뒤집는 표준 풀이이다.
개선 제안: 현재 구현이 적절해 보입니다.
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
set-matrix-zeroes/yuseok89.py
# TC: O(NM)
# SC: O(N+M)
class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
n = len(matrix)
m = len(matrix[0])
row_set = set()
col_set = set()
for row in range(0, n):
for col in range(0, m):
if matrix[row][col] == 0:
row_set.add(row)
col_set.add(col)
for row in range(0, n):
for col in range(0, m):
if row in row_set or col in col_set:
matrix[row][col] = 0
- 패턴: Hash Map / Hash Set, Greedy, Two Pointers, Dynamic Programming, Sliding Window, Binary Search, Monotonic Stack, Heap / Priority Queue, BFS, DFS, Backtracking, Divide and Conquer, Union Find, Trie, Bit Manipulation
- 설명: 행렬에서 0인 위치를 저장해두고, 저장된 행과 열에 해당하는 원소를 0으로 설정한다. 해시 셋을 이용해 인덱스 기록 패턴이 활용되며 공간 절약 없이 직관적으로 문제를 해결한다.
📊 시간/공간 복잡도 분석
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(NM) | O(n*m) | ❌ |
| Space | O(N+M) | O(n + m) | ✅ |
피드백: 필요한 행과 열의 인덱스를 저장하기 위해 두 개의 집합을 사용하고, 이후 전체 매트릭스를 순회하며 0으로 설정한다.
개선 제안: 현재 구현이 적절해 보입니다.
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
unique-paths/yuseok89.py
# TC: O(NM)
# SC: O(N)
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
cnt = [0] * n
cnt[0] = 1
for i in range(0, m):
for j in range(1, n):
cnt[j] += cnt[j - 1]
return cnt[n - 1];
- 패턴: Dynamic Programming, Greedy, Two Pointers
- 설명: 수평 미로처럼 행렬의 경로를 누적합으로 계산하는 DP 패턴으로, 메모리 절약을 위해 1차 배열로 최적화하는 기법이 보입니다. 각 셀의 경로 수를 왼쪽 셀과 위 셀의 합으로 구하는 전형적인 DP 접근입니다.
📊 시간/공간 복잡도 분석
| 유저 분석 | 실제 분석 | 결과 | |
|---|---|---|---|
| Time | O(NM) | O(m*n) | ❌ |
| Space | O(N) | O(n) | ✅ |
피드백: 1차원 DP 배열을 사용해 현재 열의 누적 경로 수를 다음 열로 업데이트한다.
개선 제안: 현재 구현이 적절해 보입니다.
| cur = head | ||
|
|
||
| while cur: | ||
| next = cur.next |
There was a problem hiding this comment.
next는 파이썬의 내장 함수라 다른 변수명을 사용하시는게 좋을 거 같습니다.
| for j in range(1, n): | ||
| cnt[j] += cnt[j - 1] | ||
|
|
||
| return cnt[n - 1]; |
There was a problem hiding this comment.
세미콜론이 잘못 들어가 있네요
| return cnt[n - 1]; | |
| return cnt[n - 1] |
| l, r = 0, 0 | ||
|
|
There was a problem hiding this comment.
for r in ... 때문에 여기 r = 0 할당은 불필요한 거 같습니다.
| while c in seen: | ||
| seen.remove(s[l]) | ||
| l += 1 |
There was a problem hiding this comment.
left를 한 칸씩 이동하고 있는데 각 문자의 인덱스를 활용하면 조금 더 최적화가 가능할 거 같습니다.
| @@ -0,0 +1,21 @@ | |||
| # TC: O(N) | |||
| # SC: O(1) | |||
There was a problem hiding this comment.
공간 복잡도 표기가 잘못되어 있네요. 수정 부탁드립니다
답안 제출 문제
작성자 체크 리스트
In Review로 설정해주세요.검토자 체크 리스트
Important
본인 답안 제출 뿐만 아니라 다른 분 PR 하나 이상을 반드시 검토를 해주셔야 합니다!