DFS with python

chanloperยท2024๋…„ 7์›” 19์ผ
0

์ž๋ฃŒ๊ตฌ์กฐ

๋ชฉ๋ก ๋ณด๊ธฐ
8/10

๐Ÿ”Ž DFS๋ž€?

  • Depth First Search์˜ ์•ฝ์ž๋กœ, ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ๋งŒํผ ๊ณ„์†ํ•ด์„œ ํƒ์ƒ‰ํ•˜๋‹ค๊ฐ€ ๊ฐˆ ์ˆ˜ ์—†๊ฒŒ ๋˜๋ฉด ๋‹ค๋ฅธ ๋ฐฉํ–ฅ์œผ๋กœ ๋‹ค์‹œ ํƒ์ƒ‰ํ•˜๋Š” ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.
    ๐Ÿช„ ๊ทธ๋ž˜ํ”„ ์ž๋ฃŒ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ผ๊ณ ๋„ ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

  • ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•˜๊ณ  ๊นŠ์ด ์šฐ์„ ์œผ๋กœ ์ธ์ ‘ํ•œ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•œ๋‹ค.
  • ๋˜, ๊ทธ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•ด์„œ ๊นŠ์ด ์šฐ์„ ์œผ๋กœ ์ธ์ ‘ํ•œ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•œ๋‹ค.
  • ์œ„ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•œ๋‹ค.

๐Ÿ”Ž DFS์˜ ๊ธฐ๋ณธ ์›์น™

  • DFS์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ์„ ๋•Œ๋Š” ํ•ญ์ƒ ์•ž์œผ๋กœ ์ฐพ์•„ ๊ฐ€์•ผํ•  ๋…ธ๋“œ์™€ ์ด๋ฏธ ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ํƒ์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.
    ๋”ฐ๋ผ์„œ, ํŠน์ • ๋…ธ๋“œ๊ฐ€ ์•ž์œผ๋กœ ์ฐพ์•„ ๊ฐ€์•ผํ•  ๋…ธ๋“œ๋ผ๋ฉด ๊ณ„์† ๊ฒ€์ƒ‰์„ ํ•˜๋Š”๊ฒƒ์ด๊ณ  ์ด๋ฏธ ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฉด ๋ฌด์‹œํ•˜๊ฑฐ๋‚˜ ์ €์žฅํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ฃผ์–ด์ง„ ๊ทธ๋ž˜ํ”„

graph = {
     1: [2, 3, 4],
     2 : [5],
     3: [5],
     4: [],
     5:  [6,7],
     6: [],
     7: [3],
 }

์žฌ๊ท€์  DFS๊ตฌํ˜„

def dfs_recursive(node,visited):
    # ๋ฐฉ๋ฌธ์ฒ˜๋ฆฌ
    visited.append(node)
	
    # ์ธ์ ‘ ๋…ธ๋“œ ๋ฐฉ๋ฌธ
    for adj in graph[node]:
        if adj not in visited:
            dfs_recursive(adj,visited)

        return visited
  • dfs_recursive ํ•จ์ˆ˜๋Š” ์žฌ๊ท€์ ์œผ๋กœ DFS๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    node : ํ˜„์žฌ ๋ฐฉ๋ฌธํ•˜๊ณ  ์žˆ๋Š” ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค
    visited : ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ ๊ธฐ๋กํ•˜๋Š” ๋ฆฌ์ŠคํŠธ์ž…๋‹ˆ๋‹ค.
  1. ๋จผ์ € visited ๋ฆฌ์ŠคํŠธ์— ํ˜„์žฌ ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ฐฉ๋ฌธ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  2. graph[node] ๋Š” ํ˜„์žฌ ๋…ธ๋“œ์˜ ์ธ์ ‘ ๋…ธ๋“œ๋“ค์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฆฌ์ŠคํŠธ์ž…๋‹ˆ๋‹ค.
  3. ๊ฐ ์ธ์ ‘ ๋…ธ๋“œ์— ๋Œ€ํ•ด ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋งŒ ์žฌ๊ท€์ ์œผ๋กœ dfs_recursive ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ทธ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•ฉ๋‹ˆ๋‹ค.
  4. ๋ชจ๋“  ์ธ์ ‘ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•œ ํ›„ visited ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์Šคํƒ์„ ์ด์šฉํ•œ DFS ๊ตฌํ˜„

def dfs_stack(start):
    visited = [] # ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ ๊ธฐ๋กํ•˜๋Š” ๋ฆฌ์ŠคํŠธ
    stack = [start] # ๋ฐฉ๋ฌธํ•  ๋…ธ๋“œ๋ฅผ ๋‹ด๋Š” ์Šคํƒ, ์‹œ์ž‘ ๋…ธ๋“œ๋กœ ์ดˆ๊ธฐํ™”

    # ์Šคํƒ์— ๋ฐฉ๋ฌธํ•  ๋…ธ๋“œ๊ฐ€ ๋‚จ์•„์žˆ๋Š” ํ•œ ์•„๋ž˜ ๋กœ์ง์„ ๋ฐ˜๋ณตํ•œ๋‹ค.
    while stack:
        top = stack.pop()  # ์ œ์ผ ์ตœ๊ทผ์— ์‚ฝ์ž…๋œ ๋…ธ๋“œ๋ฅผ ๊บผ๋ƒ„
        visited.append(top) # ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ 
    
        for adj in graph[top]:   # ํ˜„์žฌ ๋…ธ๋“œ์˜ ์ธ์ ‘ ๋…ธ๋“œ๋“ค์„ ํƒ์ƒ‰
            if adj not in visited: # ์ธ์ ‘ ๋…ธ๋“œ๊ฐ€ ๋ฐฉ๋ฌธ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด
                stack.append(adj) # ์Šคํƒ์— ์ถ”๊ฐ€ํ•˜์—ฌ ๋‚˜์ค‘์— ๋ฐฉ๋ฌธ

        return visited # ๋ฐฉ๋ฌธํ•œ ์ˆœ์„œ๋Œ€๋กœ ๋…ธ๋“œ๋“ค์„ ๋ฐ˜ํ™˜

visited ๋ฆฌ์ŠคํŠธ : ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ ๊ธฐ๋กํ•˜๊ธฐ ์œ„ํ•œ ๋ฆฌ์ŠคํŠธ์ž…๋‹ˆ๋‹ค.
stack ๋ฆฌ์ŠคํŠธ : DFS๋ฅผ ์œ„ํ•œ ์Šคํƒ์ž…๋‹ˆ๋‹ค. ์ดˆ๊ธฐ์—๋Š” ์‹œ์ž‘ ๋…ธ๋“œ์ธ 'start'๋กœ ์„ค์ •(์ดˆ๊ธฐํ™”)๋ฉ๋‹ˆ๋‹ค.
while stack : ์Šคํƒ์ด ๋น„์–ด์งˆ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค. ์Šคํƒ์— ๋‚จ์•„์žˆ๋Š” ๋…ธ๋“œ๋“ค์€ ๋ฐฉ๋ฌธํ•  ๋…ธ๋“œ๋“ค์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
top = stack.pop() : ์Šคํƒ์—์„œ ๋งจ ์œ„(์ตœ๊ทผ์— ์ถ”๊ฐ€๋œ) ๋…ธ๋“œ๋ฅผ ๊บผ๋‚ด์–ด 'top'์— ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. ์ด ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
visitde.append(top): ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ visited ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€(append)ํ•ฉ๋‹ˆ๋‹ค
for adj in graph[top] : ํ˜„์žฌ ๊บผ๋‚ธ ๋…ธ๋“œ top์˜ ์ธ์ ‘ ๋…ธ๋“œ๋“ค์„ ํƒ์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.
if adj not in visited : ์ธ์ ‘ ๋…ธ๋“œ๊ฐ€ ๋ฐฉ๋ฌธ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด, ์Šคํƒ์— ์ถ”๊ฐ€ํ•˜์—ฌ ๋‚˜์ค‘์— ๋ฐฉ๋ฌธํ•ฉ๋‹ˆ๋‹ค.
return visited : ๋ชจ๋“  ๋…ธ๋“œ๋“ค์„ ๋ฐฉ๋ฌธํ•œ ํ›„, ๋ฐฉ๋ฌธํ•œ ์ˆœ์„œ๋Œ€๋กœ ๋…ธ๋“œ๋“ค์„ ๋‹ด์€ visited ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”ฆ ์„ฌ์˜ ๊ฐœ์ˆ˜ ์ฐพ๊ธฐ

์ฒด๊ฐ ๋‚œ์ด๋„ : โญ๏ธโญ๏ธโญ๏ธโญ๏ธโ˜†

def island_dfs_stack(grid):
    # ์ƒ, ํ•˜, ์ขŒ, ์šฐ ๋ฐฉํ–ฅ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐฐ์—ด
    dx = [0,0,1,-1]
    dy = [1,-1,0,0]

    # ๊ทธ๋ฆฌ๋“œ์˜ ํ–‰๊ณผ ์—ด ๊ธธ์ด
    rows, cols = len(grid), len(grid[0])

    # ์„ฌ์˜ ๊ฐœ์ˆ˜๋ฅผ ์„ธ๋Š” ๋ณ€์ˆ˜ 'cnt'
    cnt = 0

    # ๊ทธ๋ฆฌ๋“œ์˜ ๊ฐ ์…€์„ ํ•˜๋‚˜์”ฉ ํƒ์ƒ‰
    for row in range(rows):
        for col in range(cols):
            # ํ˜„์žฌ ์…€์ด ์œก์ง€('1')๊ฐ€ ์•„๋‹ˆ๋ฉด ๊ฑด๋„ˆ๋œ€
            if grid[row][col] != '1':
                continue

            # ์ƒˆ๋กœ์šด ์„ฌ์„ ๋ฐœ๊ฒฌํ–ˆ์œผ๋ฏ€๋กœ ์„ฌ ๊ฐœ์ˆ˜๋ฅผ ์ฆ๊ฐ€์‹œํ‚ด
            cnt += 1

            # ์Šคํƒ์„ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ํ˜„์žฌ ์…€์„ ์Šคํƒ์— ์ถ”๊ฐ€
            stack = [(row,col)]

            # ์Šคํƒ์ด ๋น„์–ด์žˆ์„ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต
            while stack:
                x,y = stack.pop() # ์Šคํƒ์—์„œ ํ•˜๋‚˜์˜ ์…€์„ ๊บผ๋ƒ„
                grid[x][y] = '0' # ๊บผ๋‚ธ ์…€์„ '0'์œผ๋กœ ํ‘œ์‹œํ•˜์—ฌ ๋ฐฉ๋ฌธํ•œ ๊ฒƒ์œผ๋กœ ์ฒ˜๋ฆฌ

                # ๋„ค ๋ฐฉํ–ฅ์„ ํƒ์ƒ‰
                for i in range(4):
                    nx = x + dx [i] # ์ƒˆ๋กœ์šด x ์ขŒํ‘œ
                    ny = y + dy [i] # ์ƒˆ๋กœ์šด y ์ขŒํ‘œ

                    # ์ƒˆ๋กœ์šด ์ขŒํ‘œ๊ฐ€ ๊ทธ๋ฆฌ๋“œ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๊ฑฐ๋‚˜ , ์œก์ง€๊ฐ€ ์•„๋‹ˆ๋ฉด ๊ฑด๋„ˆ๋œ€
                    if nx < 0 or nx >= rows or ny < 0 or ny >= cols or grid[nx][ny] != '1':
                        continue

                    # ์Šคํƒ์— ์ƒˆ๋กœ์šด ์ขŒํ‘œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ DFS ์ง„ํ–‰
                    stack.append((nx,ny))

                # ํ•œ๋ฒˆ์˜ DFS ํƒ์ƒ‰์ด ๋๋‚˜๋ฉด ํ•ด๋‹น ์„ฌ์˜ ํƒ์ƒ‰์„ ์™„๋ฃŒํ•˜๊ณ  ๋‹ค์Œ ์…€๋กœ ์ด๋™

            return cnt # ์„ฌ์˜ ๊ฐœ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜

๐Ÿค•

profile
์ด๊ฒƒ ๋ญ์—์š”?

0๊ฐœ์˜ ๋Œ“๊ธ€