Skip to content

Commit 3a695f4

Browse files
committed
Invert Binary Tree
1 parent cd3d89e commit 3a695f4

File tree

2 files changed

+150
-0
lines changed

2 files changed

+150
-0
lines changed

invert-binary-tree/socow.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
"""
2+
📚 226. Invert Binary Tree
3+
4+
📌 문제 요약
5+
- 이진 트리를 좌우로 뒤집기 (거울처럼!)
6+
- 모든 노드에서 왼쪽 자식 ↔ 오른쪽 자식 교환
7+
8+
📝 문제 예시
9+
입력: 출력:
10+
4 4
11+
/ \ / \
12+
2 7 → 7 2
13+
/ \ / \ / \ / \
14+
1 3 6 9 9 6 3 1
15+
16+
🎯 핵심 알고리즘
17+
- 패턴: 재귀 (DFS) / 반복 (BFS)
18+
- 시간복잡도: O(n) - 모든 노드 방문
19+
- 공간복잡도: O(h) - h는 트리 높이 (콜스택)
20+
21+
💡 핵심 아이디어
22+
1. 현재 노드의 왼쪽/오른쪽 자식을 swap
23+
2. 왼쪽 서브트리 재귀적으로 뒤집기
24+
3. 오른쪽 서브트리 재귀적으로 뒤집기
25+
"""
26+
27+
from typing import Optional
28+
from collections import deque
29+
30+
31+
class TreeNode:
32+
def __init__(self, val=0, left=None, right=None):
33+
self.val = val
34+
self.left = left
35+
self.right = right
36+
37+
38+
# 재귀 방식 (가장 간단!)
39+
class Solution:
40+
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
41+
if not root:
42+
return None
43+
44+
# 왼쪽 ↔ 오른쪽 swap!
45+
root.left, root.right = root.right, root.left
46+
47+
# 자식들도 재귀적으로 뒤집기
48+
self.invertTree(root.left)
49+
self.invertTree(root.right)
50+
51+
return root
52+
53+
54+
# BFS 방식 (반복)
55+
class SolutionBFS:
56+
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
57+
if not root:
58+
return None
59+
60+
queue = deque([root])
61+
62+
while queue:
63+
node = queue.popleft()
64+
65+
# swap!
66+
node.left, node.right = node.right, node.left
67+
68+
# 자식들 큐에 추가
69+
if node.left:
70+
queue.append(node.left)
71+
if node.right:
72+
queue.append(node.right)
73+
74+
return root
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
"""
2+
📚 417. Pacific Atlantic Water Flow
3+
4+
📌 문제 요약
5+
- m x n 섬이 있고, 각 칸에 높이가 있음
6+
- 왼쪽/위 = 태평양(Pacific), 오른쪽/아래 = 대서양(Atlantic)
7+
- 물은 높은 곳 → 낮거나 같은 곳으로만 흐름
8+
- 두 바다 모두에 물이 도달할 수 있는 좌표 찾기!
9+
10+
📝 문제 예시
11+
heights = [
12+
[1, 2, 2, 3, 5], ← 태평양 (위)
13+
[3, 2, 3, 4, 4],
14+
[2, 4, 5, 3, 1],
15+
[6, 7, 1, 4, 5],
16+
[5, 1, 1, 2, 4] → 대서양 (아래)
17+
]
18+
↑ 태평양 (왼쪽) ↓ 대서양 (오른쪽)
19+
20+
결과: [[0,4], [1,3], [1,4], [2,2], [3,0], [3,1], [4,0]]
21+
22+
🎯 핵심 알고리즘
23+
- 패턴: BFS/DFS (역방향 탐색)
24+
- 시간복잡도: O(m × n)
25+
- 공간복잡도: O(m × n)
26+
27+
💡 핵심 아이디어
28+
1. 정방향(높→낮)으로 탐색하면 모든 점에서 시작해야 함 (비효율)
29+
2. 역방향(바다→섬)으로! 바다에서 시작해서 올라갈 수 있는 곳 탐색
30+
3. 태평양에서 갈 수 있는 곳 + 대서양에서 갈 수 있는 곳 = 정답!
31+
"""
32+
33+
from typing import List
34+
from collections import deque
35+
36+
37+
class Solution:
38+
def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:
39+
if not heights:
40+
return []
41+
42+
m, n = len(heights), len(heights[0])
43+
44+
# 각 바다에서 도달 가능한 좌표 저장
45+
pacific = set()
46+
atlantic = set()
47+
48+
def bfs(starts, reachable):
49+
queue = deque(starts)
50+
reachable.update(starts)
51+
52+
while queue:
53+
r, c = queue.popleft()
54+
55+
# 상하좌우 탐색
56+
for dr, dc in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
57+
nr, nc = r + dr, c + dc
58+
59+
# 범위 내 & 아직 안 감 & 올라갈 수 있음 (역방향!)
60+
if (0 <= nr < m and 0 <= nc < n
61+
and (nr, nc) not in reachable
62+
and heights[nr][nc] >= heights[r][c]):
63+
queue.append((nr, nc))
64+
reachable.add((nr, nc))
65+
66+
# 태평양: 왼쪽 + 위쪽 가장자리에서 시작
67+
pacific_starts = [(i, 0) for i in range(m)] + [(0, j) for j in range(n)]
68+
bfs(pacific_starts, pacific)
69+
70+
# 대서양: 오른쪽 + 아래쪽 가장자리에서 시작
71+
atlantic_starts = [(i, n-1) for i in range(m)] + [(m-1, j) for j in range(n)]
72+
bfs(atlantic_starts, atlantic)
73+
74+
# 교집합 = 두 바다 모두 도달 가능!
75+
return list(pacific & atlantic)
76+

0 commit comments

Comments
 (0)