Coding Test/Python

[프로그래머스] 게임 맵 최단거리 (level2, python)

lim.dev 2024. 1. 18. 15:26

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

아이디어

최단거리를 찾는 문제라서 bfs를 사용해서 풀었다.

    def bfs(x, y, N, M):
        nonlocal visited
        
        queue = deque([(x, y, 1)])
        
        while queue:
            x, y, l = queue.popleft()
            
            if x == N-1 and y == M-1: return l
            
            for dx, dy in dv:
                nx = x + dx
                ny = y + dy
                                
                if nx < 0 or nx >= N or ny < 0 or ny >= M or visited[nx][ny] == 1 or maps[nx][ny] == 0: 
                    continue
                
                visited[nx][ny] = 1
                queue.append((nx, ny, l+1))
        return -1

x, y 는 좌표 정보이고, l은 이동한 거리이다.

만약 큐만큼 돌았는데 리턴값이 없다면 -1을 리턴한다. (갈 수 없다는 뜻이므로)

 

구현할 때 visited 리스트를 처음에는 아래와 같이 선언하였는데,

visited = [[0] * M] * N

 

이렇게 선언하니 문제가 있었다.

파이썬 유저라면 눈치챘겠지만.. [[0]*M] 인 리스트를 N번 복제(얕은 복사)해서 넣는다.

visited 리스트가 모두 같은 주소를 바라보게 된다.

만약 첫 번째 리스트를 [1, 0, 0]으로 수정했다면, 두번째도, 세번째도 모두 [1, 0, 0]이 되는 것이다.

 

그래서 list comprehension으로 다시 선언해주었다..

visited = [[ 0 for _ in range(M)] for _ in range(N)]

 

 

전체 코드

from collections import deque

def solution(maps):
    N = len(maps)
    M = len(maps[0])
    visited = [[ 0 for _ in range(M)] for _ in range(N)]
    
    dv = [(0, 1), (0, -1), (1, 0), (-1, 0)]
    
    def bfs(x, y, N, M):
        nonlocal visited
        
        queue = deque([(x, y, 1)])
        
        while queue:
            x, y, l = queue.popleft()
            
            if x == N-1 and y == M-1: return l
            
            for dx, dy in dv:
                nx = x + dx
                ny = y + dy
                                
                if nx < 0 or nx >= N or ny < 0 or ny >= M or visited[nx][ny] == 1 or maps[nx][ny] == 0: 
                    continue
                
                visited[nx][ny] = 1
                queue.append((nx, ny, l+1))
        return -1
    
    return bfs(0, 0, N, M)