πŸš€ Development/Problem Solving

[ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€] κ²Œμž„ λ§΅ μ΅œλ‹¨κ±°λ¦¬(Lv.2) - 파이썬(Python)

Jay Din 2024. 9. 5. 20:35
728x90
λ°˜μ‘ν˜•

문제

https://school.programmers.co.kr/learn/courses/30/lessons/1844

 

ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€

μ½”λ“œ μ€‘μ‹¬μ˜ 개발자 μ±„μš©. μŠ€νƒ 기반의 ν¬μ§€μ…˜ λ§€μΉ­. ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€μ˜ 개발자 λ§žμΆ€ν˜• ν”„λ‘œν•„μ„ λ“±λ‘ν•˜κ³ , λ‚˜μ™€ 기술 ꢁ합이 잘 λ§žλŠ” 기업듀을 λ§€μΉ­ λ°›μœΌμ„Έμš”.

programmers.co.kr

 

풀이

이 μ½”λ“œλŠ” μ£Όμ–΄μ§„ maps μ—μ„œ BFS(λ„ˆλΉ„ μš°μ„  탐색)을 μ‚¬μš©ν•˜μ—¬ 좜발점 (0, 0)μ—μ„œ 도착점 (m-1, n-1) κΉŒμ§€μ˜ μ΅œλ‹¨ 경둜λ₯Ό μ°Ύμ•„λ‚΄λŠ” 문제λ₯Ό ν•΄κ²°ν•˜λŠ” μ½”λ“œμž…λ‹ˆλ‹€.

각 μΉΈμ—μ„œ 갈 수 μžˆλŠ” κ²½λ‘œλŠ” 1둜 ν‘œμ‹œλ˜λ©°, 0은 벽으둜 갈 수 μ—†λŠ” 경둜λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.

 

1. λ³€μˆ˜ μ„€λͺ… 및 초기 μ„€μ •

m = len(maps)       # ν–‰μ˜ 수
n = len(maps[0])    # μ—΄μ˜ 수
  • m 은 맡의 ν–‰(row) 수λ₯Ό λ‚˜νƒ€λ‚΄λ©°, n은 μ—΄(column) 수λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€. 즉, 맡은 m x n ν¬κΈ°μž…λ‹ˆλ‹€.
visited = [[False]*n for _ in range(m)]
  • visitedλŠ” λ°©λ¬Έ μ—¬λΆ€λ₯Ό κΈ°λ‘ν•˜λŠ” 2차원 λ¦¬μŠ€νŠΈμž…λ‹ˆλ‹€.
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
  • dx 와 dy λŠ” μƒν•˜μ’Œμš° 이동을 μœ„ν•œ λ°©ν–₯μž…λ‹ˆλ‹€. 이 값듀을 μ΄μš©ν•΄ 각각 μœ„, μ•„λž˜, 쒌, 우둜 이동할 수 μžˆμŠ΅λ‹ˆλ‹€.

 

2. BFS ν•¨μˆ˜ μ„€λͺ…

def bfs(x, y):
    q = deque()
    q.append([x, y])
    visited[x][y] = True
  • bfs ν•¨μˆ˜λŠ” (x, y) μ’Œν‘œμ—μ„œ BFS 탐색을 μ‹œμž‘ν•©λ‹ˆλ‹€.
  • dequeλŠ” 큐 자료ꡬ쑰둜, BFSλ₯Ό μˆ˜ν–‰ν•˜κΈ°μ— μ ν•©ν•©λ‹ˆλ‹€. 첫 μ‹œμž‘μ  (0, 0)을 큐에 λ„£κ³  visited λ₯Ό true둜 μ„€μ •ν•©λ‹ˆλ‹€.
while q:
    xx, yy = q.popleft()
  • 큐가 λΉ„μ–΄ μžˆμ§€ μ•Šμ€ λ™μ•ˆ BFSλ₯Ό μˆ˜ν–‰ν•©λ‹ˆλ‹€. q.popleft() λŠ” νμ—μ„œ κ°€μž₯ λ¨Όμ € λ“€μ–΄κ°„ μ’Œν‘œλ₯Ό κΊΌλƒ…λ‹ˆλ‹€.
for i in range(4):
    nx = xx + dx[i]
    ny = yy + dy[i]
  • μƒν•˜μ’Œμš°λ‘œ μ΄λ™ν•˜κΈ° μœ„ν•΄ dx, dy λ°©ν–₯을 μ‚¬μš©ν•΄ μ’Œν‘œ (nx, ny)λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
if 0 <= nx < m and 0 <= ny < n:
    if maps[nx][ny] != 0 and not visited[nx][ny]:
        visited[nx][ny] = True
        maps[nx][ny] = maps[xx][yy] + 1
        q.append([nx, ny])
  • μƒˆλ‘œμš΄ μ’Œν‘œ (ny, nx)κ°€ 맡의 λ²”μœ„λ₯Ό λ²—μ–΄λ‚˜μ§€ μ•Šκ³  (0 <= nx < m and 0 <= ny < n), 벽이 μ•„λ‹Œ κ³³(maps[nx][ny] != 0) 이며 아직 λ°©λ¬Έν•˜μ§€ μ•Šμ€ κ³³ ( not visited[nx][ny] ) 인 κ²½μš°μ—λ§Œ μ΄λ™ν•©λ‹ˆλ‹€.
  • 이동할 수 있으면 visited[nx][ny] = True둜 λ°©λ¬Έ μ—¬λΆ€λ₯Ό κΈ°λ‘ν•˜κ³ , κ·Έ μœ„μΉ˜μ˜ 값을 ν˜„μž¬ μœ„μΉ˜ maps[xx][yy]에 1을 λ”ν•œ κ°’μœΌλ‘œ κ°±μ‹ ν•©λ‹ˆλ‹€. μ΄λŠ” BFS νŠΉμ„±μƒ μ΅œλ‹¨ κ²½λ‘œμž„μ„ 보μž₯ν•©λ‹ˆλ‹€.
  • 이후 (nx, ny) μ’Œν‘œλ₯Ό 큐에 μΆ”κ°€ν•˜μ—¬ 계속 νƒμƒ‰ν•©λ‹ˆλ‹€.

 

3. μ΅œμ’… κ²°κ³Ό 계산

if maps[m-1][n-1] == 1 or maps[m-1][n-1] == 0:
    answer = -1
else:
    answer = maps[m-1][n-1]

 

  • BFS 탐색이 λλ‚œ ν›„ 도착점 (m-1, n-1)의 값이 1μ΄κ±°λ‚˜ 0이면, μ΄λŠ” κ²½λ‘œκ°€ μ—†μŒμ„ μ˜λ―Έν•˜λ―€λ‘œ answer = -1둜 μ„€μ •ν•©λ‹ˆλ‹€. 1은 도착점이 초기 μƒνƒœμΈ 경우이며, 0은 도착할 수 μ—†λŠ” κ²½μš°μž…λ‹ˆλ‹€.
  • λ„μ°©μ μ˜ 값이 1보닀 크면, μ΄λŠ” μ‹œμž‘μ μ—μ„œ λ„μ°©μ κΉŒμ§€μ˜ μ΅œλ‹¨ 경둜의 길이λ₯Ό λ‚˜νƒ€λ‚΄λ―€λ‘œ, κ·Έ 값을 answer에 μ €μž₯ν•©λ‹ˆλ‹€.

 

 

μ΅œμ’… μ½”λ“œ

from collections import deque

def solution(maps):
    
    answer = 0
    m = len(maps)       # ν–‰μ˜ 수
    n = len(maps[0])    # μ—΄μ˜ 수 
    
    visited = [[False]*n for _ in range(m)]
    
    dx = [-1,1,0,0]
    dy = [0,0,-1,1]
    
    def bfs(x, y):
        q = deque()
        q.append([x,y])
        visited[x][y] = True
        
        while q:
            xx, yy = q.popleft()
            
            for i in range(4):
                nx = xx+dx[i]
                ny = yy+dy[i]
                
                if 0<= nx < m and 0 <= ny < n:
                    if maps[nx][ny] != 0 and not visited[nx][ny]:
                        visited[nx][ny] = True
                        maps[nx][ny] = maps[xx][yy] + 1
                        q.append([nx, ny])
        
    bfs(0,0)
    
    
    if maps[m-1][n-1] == 1 or maps[m-1][n-1] == 0:
        answer = -1
    else:
        answer = maps[m-1][n-1]
        
    return answer

 

728x90
λ°˜μ‘ν˜•