[Algorithm] DFS&BFS
๐ฃ
๋ณธ ํฌ์คํธ๋ โ์ด๊ฒ์ด ์ทจ์
์ ์ํ ์ฝ๋ฉ ํ
์คํธ๋ค with ํ์ด์ฌโ์ ๊ณต๋ถํ๊ณ ์์ฑํ์์ต๋๋ค :)
click > (์ด์ฝํ
2021) ์ด๊ฒ์ด ์ทจ์
์ ์ํ ์ฝ๋ฉ ํ
์คํธ๋ค with ํ์ด์ฌ
DFS/BFS
์ด๋ก
-
ํ์(Search)
๋ง์ ์์ ๋ฐ์ดํฐ ์ค์์ ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ฐพ๋ ๊ณผ์ โ ๊ทธ๋ํ, ํธ๋ฆฌ ๋ฑ์ ์๋ฃ๊ตฌ์กฐ์์ ๋ง์ด ๋ค๋ฃฌ๋ค.
์๋ฃ๊ตฌ์กฐ(Data Structure)
๋ฐ์ดํฐ๋ฅผ ํํํ๊ณ ๊ด๋ฆฌํ๊ณ ์ฒ๋ฆฌํ๊ธฐ ์ํ ๊ตฌ์กฐ
- Stack : ์ ์
ํ์ถ (First In Last Out) or ํ์
์ ์ถ (Last In First Out)
-
[์์ 5-1] ์คํ ์์
# stack example stack = [] # ์ฝ์ (5)-์ฝ์ (2)-์ฝ์ (3)-์ฝ์ (7)-์ญ์ ()-์ฝ์ (1)-์ฝ์ (4)-์ญ์ () stack.append(5) stack.append(2) stack.append(3) stack.append(7) stack.pop() stack.append(1) stack.append(4) stack.pop() print(stack) # ์ตํ๋จ ์์๋ถํฐ print(stack[::-1]) # ์ต์๋จ ์์๋ถํฐ
-
- Queue : ์ ์
์ ์ถ (First In First Out)
-
[์์ 5-2] ํ ์์
from collections import deque # ํ ๊ตฌํ์ ์ํด deque ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉ queue = deque() # ์ฝ์ (5)-์ฝ์ (2)-์ฝ์ (3)-์ฝ์ (7)-์ญ์ ()-์ฝ์ (1)-์ฝ์ (4)-์ญ์ () queue.append(5) queue.append(2) queue.append(3) queue.append(7) queue.popleft() queue.append(1) queue.append(4) queue.popleft() print(queue) # ๋จผ์ ๋ค์ด์จ ์์๋๋ก ์ถ๋ ฅ queue.reverse() # ์ญ์์ผ๋ก ์ฌ์ ๋ ฌ print(queue) # ๋์ค์ ๋ค์ด์จ ์์๋ถํฐ ์ถ๋ ฅ
-
- Recursive Function : ์๊ธฐ ์์ ์ ํธ์ถํ๋ ํจ์
-
[์์ 5-3] ์ฌ๊ทํจ์ ์์
def factorial_iterative(n): result = 1 for i in range(1,n+1): result *= i return result def factorial_recursive(n): if n <= 1: return 1 return n * factorial_recursive(n-1) print(factorial_iterative(5)) print(factorial_recursive(5))
-
-
Graph์ ๊ธฐ๋ณธ ๊ตฌ์กฐ
- ๋ ธ๋ (Node) : ์ ์ (Vertex)๋ผ๊ณ ๋ ํ๋ค.
- ๊ฐ์ (Edge) : ๋ ๋ ธ๋๋ฅผ ์ฐ๊ฒฐํ๋ค.
- Graph์ ํํ ๋ฐฉ์
- ์ธ์ ํ๋ ฌ (Adjacency Matrix) : 2์ฐจ์ ๋ฐฐ์ด๋ก ํํ
- ๋ชจ๋ ๊ด๊ณ๋ฅผ ์ ์ฅํ๋ฏ๋ก ๋ฉ๋ชจ๋ฆฌ ๋ง์ด ์ฌ์ฉ
-
[์์ 5-4] ์ธ์ ํ๋ ฌ ์์
INF = 999999999 # 2์ฐจ์ ๋ฆฌ์คํธ๋ฅผ ์ด์ฉํ์ฌ ์ธ์ ํ๋ ฌ ํํ graph = [ [0, 7, 5], [7, 0, INF], [5, INF, 0] ] print(graph)
- ์ธ์ ๋ฆฌ์คํธ (Adjacency List) : ๋ฆฌ์คํธ๋ก ํํ
- ํน์ ๋ ๋ ธ๋๊ฐ ์ฐ๊ฒฐ๋์ด ์๋์ง์ ๋ํ ์ ๋ณด ์ป๋ ์๋ ๋๋ฆผ
-
[์์ 5-5] ์ธ์ ๋ฆฌ์คํธ ์์
# ํ์ด 3๊ฐ์ธ 2์ฐจ์ ๋ฆฌ์คํธ๋ก ์ธ์ ๋ฆฌ์คํธ ํํ graph = [[] for _ in range(3)] # ๋ ธ๋ 0์ ์ฐ๊ฒฐ๋ ๋ ธ๋ ์ ๋ณด ์ ์ฅ(๋ ธ๋, ๊ฑฐ๋ฆฌ) graph[0].append((1,7)) graph[0].append((2,5)) # ๋ ธ๋ 1์ ์ฐ๊ฒฐ๋ ๋ ธ๋ ์ ๋ณด ์ ์ฅ(๋ ธ๋, ๊ฑฐ๋ฆฌ) graph[1].append((0,7)) # ๋ ธ๋ 2์ ์ฐ๊ฒฐ๋ ๋ ธ๋ ์ ๋ณด ์ ์ฅ(๋ ธ๋, ๊ฑฐ๋ฆฌ) graph[2].append((0,5)) print(graph)
- ์ธ์ ํ๋ ฌ (Adjacency Matrix) : 2์ฐจ์ ๋ฐฐ์ด๋ก ํํ
DFS(Depth-First Search)
๊น์ด ์ฐ์ ํ์์ผ๋ก ๊ทธ๋ํ์์ ๊น์ ๋ถ๋ถ์ ๋จผ์ ํ์ํ๋ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก Stack ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ด์ฉํ๋ค.
- ํ์ ์์ ๋ ธ๋๋ฅผ ์คํ์ ์ฝ์ ํ๊ณ ๋ฐฉ๋ฌธ์ฒ๋ฆฌ๋ฅผ ํ๋ค.
- ์คํ์ ์ต์๋จ ๋ ธ๋์ ๋ฐฉ๋ฌธํ์ง ์์ ์ธ์ ๋ ธ๋๊ฐ ์์ผ๋ฉด ๊ทธ ์ธ์ ๋ ธ๋๋ฅผ ์คํ์ ๋ฃ๊ณ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ๋ฅผ ํ๋ค. ๋ฐ๋ฌธํ์ง ์์ ์ธ์ ๋ ธ๋๊ฐ ์์ผ๋ฉด ์คํ์์ ์ต์๋จ ๋ ธ๋๋ฅผ ๊บผ๋ธ๋ค.
- 2์ ๊ณผ์ ์ ๋ ์ด์ ์ํํ ์ ์์ ๋๊น์ง ๋ฐ๋ณตํ๋ค.
๋ฐ์ดํฐ ๊ฐ์๊ฐ N๊ฐ์ธ ๊ฒฝ์ฐ O(N)์ ์๊ฐ ๋ณต์ก๋๋ฅผ ๊ฐ์ง๋ค.
-
[์์ 5-6] DFS ์์
# DFS ๋ฉ์๋ ์ ์ def dfs(graph, v, visited): # ํ์ฌ ๋ ธ๋๋ฅผ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ visited[v] = True print(v, end=' ') # ํ์ฌ ๋ ธ๋์ ์ฐ๊ฒฐ๋ ๋ค๋ฅธ ๋ ธ๋๋ฅผ ์ฌ๊ท์ ์ผ๋ก ๋ฐฉ๋ฌธ for i in graph[v]: if not visited[i]: dfs(graph, i, visited) # ๊ฐ ๋ ธ๋๊ฐ ์ฐ๊ฒฐ๋ ์ ๋ณด๋ฅผ ๋ฆฌ์คํธ ์๋ฃํ์ผ๋ก ํํ(2์ฐจ์ ๋ฆฌ์คํธ) graph = [ [], [2,3,8], [1,7], [1,4,5], [3,5], [3,4], [7], [2,6,8], [1,7] ] # ๊ฐ ๋ ธ๋๊ฐ ๋ฐฉ๋ฌธ๋ ์ ๋ณด๋ฅผ ๋ฆฌ์คํธ ์๋ฃ # ํ์ผ๋ก ํํ(1์ฐจ์ ๋ฆฌ์คํธ) visited = [False] * 9 # ์ ์๋ DFS ํจ์ ํธ์ถ dfs(graph, 1, visited)
BFS(Breadth First Search)
๋๋น ์ฐ์ ํ์์ผ๋ก ๊ฐ๊น์ด ๋ ธ๋๋ถํฐ ํ์ํ๋ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก Queue ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ด์ฉํ๋ค.
- ํ์ ์์ ๋ ธ๋๋ฅผ ํ์ ์ฝ์ ํ๊ณ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ๋ฅผ ํ๋ค.
- ํ์์ ๋ ธ๋๋ฅผ ๊บผ๋ด ํด๋น ๋ ธ๋์ ์ธ์ ๋ ธ๋ ์ค์์ ๋ฐฉ๋ฌธํ์ง ์์ ๋ ธ๋๋ฅผ ๋ชจ๋ ํ์ ์ฝ์ ํ๊ณ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ๋ฅผ ํ๋ค.
- 2์ ๊ณผ์ ์ ๋ ์ด์ ์ํํ ์ ์์ ๋๊น์ง ๋ฐ๋ณตํ๋ค.
๋ฐ์ดํฐ ๊ฐ์๊ฐ N๊ฐ์ธ ๊ฒฝ์ฐ O(N)์ ์๊ฐ ๋ณต์ก๋๋ฅผ ๊ฐ์ง๋ฉฐ, ์ค์ ์ํ ์๊ฐ์ DFS๋ณด๋ค ์ข์ ํธ์ด๋ค.
-
[์์ 5-7] BFS ์์
from collections import deque # BFS ๋ฉ์๋ ์ ์ def bfs(graph, start, visited): # ํ ๊ตฌํ์ ์ํด deque ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ queue = deque([start]) # ํ์ฌ ๋ ธ๋๋ฅผ ๋ฐฉ๋ฌธ์ฒ๋ฆฌ visited[start] = True # ํ๊ฐ ๋น๋๊น์ง ๋ฐ๋ณต while queue: # ํ์์ ํ๋์ ์์๋ฅผ ๋ฝ์ ์ถ๋ ฅ v = queue.popleft() print(v, end=" ") # ํด๋น ์์์ ์ฐ๊ฒฐ๋, ์์ง ๋ฐฉ๋ฌธํ์ง ์์ ์์๋ค์ ํ์ ์ฝ์ for i in graph[v]: if not visited[i]: queue.append(i) visited[i] = True # ๊ฐ ๋ ธ๋๊ฐ ์ฐ๊ฒฐ๋ ์ ๋ณด๋ฅผ ๋ฆฌ์คํธ ์๋ฃํ์ผ๋ก ํํ(2์ฐจ์ ๋ฆฌ์คํธ) graph = [ [], [2,3,8], [1,7], [1,4,5], [3,5], [3,4], [7], [2,6,8], [1,7] ] # ๊ฐ ๋ ธ๋๊ฐ ๋ฐฉ๋ฌธ๋ ์ ๋ณด๋ฅผ ๋ฆฌ์คํธ ์๋ฃ # ํ์ผ๋ก ํํ(1์ฐจ์ ๋ฆฌ์คํธ) visited = [False] * 9 # ์ ์๋ DFS ํจ์ ํธ์ถ bfs(graph, 1, visited)
์ค์ ๋ฌธ์
[์ค์ ๋ฌธ์ 1] ์๋ฃ์ ์ผ๋ ค ๋จน๊ธฐ
N, M = map(int, input().split())
graph = []
for i in range(N):
graph.append(list(map(int, input())))
# DFS๋ก ํน์ ํ ๋
ธ๋๋ฅผ ๋ฐฉ๋ฌธํ ๋ค์ ์ฐ๊ฒฐ๋ ๋ชจ๋ ๋
ธ๋๋ค๋ ๋ฐฉ๋ฌธ
def dfs(x,y):
if x <= -1 or x >= N or y <= -1 or y >= N:
return False
if graph[x][y] == 0:
graph[x][y] = 1
dfs(x - 1, y)
dfs(x, y - 1)
dfs(x + 1, y)
dfs(x, y + 1)
return False
result = 0
for i in range(N):
for j in range(M):
if dfs(i,j) == True:
result += 1
print(result)
[์ค์ ๋ฌธ์ 2] ๋ฏธ๋ก ํ์ถ
from collections import deque
# N, M์ ๊ณต๋ฐฑ์ผ๋ก ๊ตฌ๋ถํ์ฌ ์
๋ ฅ๋ฐ๊ธฐ
n, m = map(int, input().split())
# 2์ฐจ์ ๋ฆฌ์คํธ์ ๋งต ์ ๋ณด ์
๋ ฅ๋ฐ๊ธฐ
graph = []
for i in range(n):
graph.append(list(map(int, input())))
# ์ด๋ํ ๋ค ๋ฐฉํฅ ์ ์
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
# BFS ๊ตฌํ
def bfs(x, y):
# ํ ๊ตฌํ์ ์ํด deque ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ
queue = deque()
queue.append((x,y))
# ํ๊ฐ ๋น ๋๊น์ง ๋ฐ๋ณต
while queue:
x, y = queue.popleft()
# ํ์ฌ ์์น์์ ๋ค ๋ฐฉํฅ์ผ๋ก ์์น ํ์ธ
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if nx < 0 or ny < 0 or nx >= n or ny >= m:
continue
if graph[nx][ny] == 0:
continue
# ํด๋น ๋
ธ๋๋ฅผ ์ฒ์ ๋ฐฉ๋ฌธํ๋ ๊ฒฝ์ฐ ์ต๋จ ๊ฑฐ๋ฆฌ ๊ธฐ๋ก
if graph[nx][ny] == 1:
graph[nx][ny] = graph[x][y] + 1
queue.append((nx,ny))
# ๊ฐ์ฅ ์ค๋ฅธ์ชฝ ์๋(n,m)๊น์ง ์ต๋จ ๊ฑฐ๋ฆฌ ๋ฐํ
return graph[n-1][m-1]
print(bfs(0,0))
๋๊ธ๋จ๊ธฐ๊ธฐ