[sangbeenmoon] WEEK 07 Solutions - #2805
Conversation
📊 sangbeenmoon 님의 학습 현황이번 주 제출 문제
누적 학습 요약
문제 풀이 현황
🤖 이 댓글은 GitHub App을 통해 자동으로 작성되었습니다. 🔢 API 사용량 (gpt-5-nano)
|
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
longest-substring-without-repeating-characters/sangbeenmoon.py
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
start = 0
last_seen = {}
answer = 0
for i,ch in enumerate(s):
if ch in last_seen:
if start < last_seen[ch]:
start = last_seen[ch] + 1
last_seen[ch] = i
answer = max(answer, i - start + 1)
return answer
# ------
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
left = 0
right = 0
answer = 0
dictionary = {}
for i,ch in enumerate(s):
right += 1
if ch not in dictionary:
dictionary[ch] = i
else:
idx = dictionary[ch]
if left <= idx:
left = idx + 1
dictionary[ch] = i
print(right, left)
answer = max(answer, right - left)
return answer- 패턴: Hash Map / Hash Set, Sliding Window
- 설명: 두 배열의 인덱스 차이로 부분 문자열의 길이를 실시간으로 갱신하는 Sliding Window 패턴으로, 중복 문자 위치를 해시 맵으로 추적하여 윈도우를 좌우로 조정합니다.
📊 시간/공간 복잡도 분석
ℹ️ 이 파일에는 2가지 풀이가 포함되어 있어 각각 분석합니다.
풀이 1: Solution.lengthOfLongestSubstring — Time: O(n) / Space: O(min(n, σ))
| 복잡도 | |
|---|---|
| Time | O(n) |
| Space | O(min(n, σ)) |
피드백: 각 문자 마지막 인덱스를 기록하고 윈도우 시작을 중복 위치 바로 다음으로 옮겨 중복 없이 구간을 확장한다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 2: Solution.lengthOfLongestSubstring — Time: O(n) / Space: O(min(n, σ))
| 복잡도 | |
|---|---|
| Time | O(n) |
| Space | O(min(n, σ)) |
피드백: 딕셔너리에 최근 위치를 저장하고 중복 시 왼쪽 포인터를 갱신한다. 다만 불필요한 출력(print)이 있어 성능/출력 측면에서 제거 권장.
개선 제안: 출력문 제거 후 최적화 가능.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
number-of-islands/sangbeenmoon.py
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
m,n = len(grid[0]), len(grid)
visited = [[False] * m for _ in range(n)]
dx = [0,0, -1, 1]
dy = [-1,1,0,0]
def dfs(xx:int, yy:int):
for d in range(4):
nx = xx + dx[d]
ny = yy + dy[d]
if 0 <= nx and nx < m and 0 <= ny and ny < n and grid[ny][nx] == "1":
if not visited[ny][nx]:
visited[ny][nx] = True
dfs(nx, ny)
answer = 0
for y in range(n):
for x in range(m):
if grid[y][x] == "1" and not visited[y][x]:
answer = answer + 1
dfs(x,y)
return answer
# ------
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
x_len , y_len = len(grid[0]), len(grid)
visited = [[False] * x_len for _ in range(y_len)]
dx = [0,0,-1,1]
dy = [-1,1,0,0]
def dfs(xx:int, yy:int):
for d in range(4):
nx = xx + dx[d]
ny = yy + dy[d]
if 0 <= nx and nx < x_len and 0 <= ny and ny < y_len and grid[ny][nx] == "1":
if not visited[ny][nx]:
visited[ny][nx] = True
dfs(nx,ny)
return
answer = 0
for xx in range(x_len):
for yy in range(y_len):
if grid[yy][xx] == "1" and not visited[yy][xx]:
answer += 1
visited[yy][xx] = True
dfs(xx,yy)
return answer
- 패턴: Depth-First Search, Hash Map / Hash Set
- 설명: 그리드를 DFS로 탐색하며 연결된 땅을 방문처리하는 방식으로 섬의 수를 세는 패턴이다. 방문 여부를 추적하는 visited 배열 사용도 특징적이며, 재귀 DFS로 인접 칸을 재귀적으로 방문한다.
📊 시간/공간 복잡도 분석
ℹ️ 이 파일에는 2가지 풀이가 포함되어 있어 각각 분석합니다.
풀이 1: Solution.numIslands — Time: O(mn) / Space: O(mn)
| 복잡도 | |
|---|---|
| Time | O(mn) |
| Space | O(mn) |
피드백: 전체 격자를 순회하며 방문 여부를 추적하고 인접 노드를 재귀적으로 탐색한다.
개선 제안: 재귀 깊이가 큰 경우 스택 오버플로를 피하기 위해 BFS로 바꾸거나 수동 스택으로 구현 고려.
풀이 2: Solution.numIslands — Time: O(mn) / Space: O(mn)
| 복잡도 | |
|---|---|
| Time | O(mn) |
| Space | O(mn) |
피드백: 2차원 방문 배열과 방향 벡터를 활용한 표준 DFS 구현이다.
개선 제안: 현 구현이 적절해 보입니다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
set-matrix-zeroes/sangbeenmoon.py
# SC : O(m+n)
class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
m,n = len(matrix), len(matrix[0])
row_dict = {}
col_dict = {}
for r in range(m):
for c in range(n):
if matrix[r][c] == 0:
row_dict[r] = True
col_dict[c] = True
for r in range(m):
for c in range(n):
if r in row_dict or c in col_dict:
matrix[r][c] = 0
# ---------
# SC : O(1)
class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
r_len , c_len = len(matrix), len(matrix[0])
set_zero_first_col = any(matrix[r][0] == 0 for r in range(r_len))
for r in range(r_len):
for c in range(1, c_len): # c는 1부터
if matrix[r][c] == 0:
matrix[r][0] = 0
matrix[0][c] = 0
for r in range(1, r_len):
for c in range(1, c_len):
if matrix[r][0] == 0 or matrix[0][c] == 0:
matrix[r][c] = 0
if matrix[0][0] == 0: # 0행 먼저
for c in range(c_len):
matrix[0][c] = 0
if set_zero_first_col: # 0열 나중
for r in range(r_len):
matrix[r][0] = 0
- 패턴: Dynamic Programming, Hash Map / Hash Set, Greedy, Divide and Conquer, Two Pointers, Sliding Window, Fast & Slow Pointers, BFS, DFS, Backtracking, Binary Search, Monotonic Stack, Heap / Priority Queue, Union Find, Trie, Bit Manipulation
- 설명: 코드는 0으로 행과 열을 표시해 행/열을 0으로 만드는 방식으로 매트릭스를 수정한다. 첫 번째 구현에서는 행과 열을 해시 맵으로 추적하고, 두 번째 구현은 상수 공간으로 매트릭스의 첫 행과 첫 열을 표식으로 재활용한다. 이는 공간 최적화와 표식 기반 처리의 패턴이다.
📊 시간/공간 복잡도 분석
ℹ️ 이 파일에는 2가지 풀이가 포함되어 있어 각각 분석합니다.
풀이 1: Solution.setZeroes — Time: O(mn) / Space: O(m + n)
| 복잡도 | |
|---|---|
| Time | O(mn) |
| Space | O(m + n) |
피드백: 초기 스캔에서 제로가 있는 행/열을 기록하고, 이후 한 번에 해당 행/열의 원소를 0으로 바꾼다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 2: Solution.setZeroes — Time: O(mn) / Space: O(1)
| 복잡도 | |
|---|---|
| Time | O(mn) |
| Space | O(1) |
피드백: 다음에 한 번의 스캔으로 원소를 0으로 바꾸기 위한 상위 상태를 유지한다.
개선 제안: 현 구현이 적절해 보입니다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
There was a problem hiding this comment.
🏷️ 알고리즘 패턴 분석
unique-paths/sangbeenmoon.py
# dp[r][c] = dp[r-1][c] + dp[r][c-1]
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
dp = [[1] * n for _ in range(m)]
for r in range(m):
for c in range(n):
if r == 0 or c == 0:
continue
dp[r][c] = dp[r-1][c] + dp[r][c-1]
return dp[m-1][n-1]
# ------------
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
dp = [[1] * n for _ in range(m)]
for r in range(1,m):
for c in range(1,n):
dp[r][c] = dp[r-1][c] + dp[r][c-1]
return dp[m-1][n-1]- 패턴: Dynamic Programming
- 설명: 두 좌표의 경로 수를 더해가는 DP 배열 정의로 최단 경로/경로 수를 구하는 전형적인 동적 계획법 문제 풀이 패턴입니다.
📊 시간/공간 복잡도 분석
ℹ️ 이 파일에는 2가지 풀이가 포함되어 있어 각각 분석합니다.
풀이 1: Solution.uniquePaths — Time: O(mn) / Space: O(mn)
| 복잡도 | |
|---|---|
| Time | O(mn) |
| Space | O(mn) |
피드백: 초기화된 1의 행/열에서 시작해 중복 없는 경로 수를 누적한다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 2: Solution.uniquePaths — Time: O(mn) / Space: O(mn)
| 복잡도 | |
|---|---|
| Time | O(mn) |
| Space | O(mn) |
피드백: 직관적으로 풀이가 명확하며 시간/공간 복잡도도 일반적인 해법과 같다.
개선 제안: 현재 구현이 적절해 보입니다.
💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!
ICE0208
left a comment
There was a problem hiding this comment.
고생 많으셨습니다! 몇 가지 코멘트 남겨두었습니다~ 🙂
|
|
||
| visited = [[False] * x_len for _ in range(y_len)] | ||
|
|
There was a problem hiding this comment.
별도의 visited 배열을 사용하지 않고, 방문한 grid의 값을 직접 변경하는 in-place 방식으로도 최적화가 가능해 보입니다!
|
|
||
| set_zero_first_col = any(matrix[r][0] == 0 for r in range(r_len)) | ||
|
|
||
| for r in range(r_len): | ||
| for c in range(1, c_len): # c는 1부터 | ||
| if matrix[r][c] == 0: | ||
| matrix[r][0] = 0 | ||
| matrix[0][c] = 0 | ||
|
|
There was a problem hiding this comment.
matrix[0][0]을 첫 번째 행의 마커처럼 활용하면 set_zero_first_row 같은 별도의 변수 없이도 처리할 수 있었군요! 🫢
| dp = [[1] * n for _ in range(m)] | ||
|
|
||
| for r in range(1,m): | ||
| for c in range(1,n): | ||
| dp[r][c] = dp[r-1][c] + dp[r][c-1] |
There was a problem hiding this comment.
현재 2차원 DP를 사용하고 있는데, 1차원 DP로 공간 복잡도를 최적화해서 풀어보셔도 좋을 것 같습니다!
|
|
||
| answer = 0 | ||
|
|
||
| dictionary = {} |
| left = idx + 1 | ||
| dictionary[ch] = i | ||
|
|
||
| print(right, left) |
답안 제출 문제
작성자 체크 리스트
In Review로 설정해주세요.검토자 체크 리스트
Important
본인 답안 제출 뿐만 아니라 다른 분 PR 하나 이상을 반드시 검토를 해주셔야 합니다!