알고리즘/test

Python) 프로그래머스 - 미로 탈출

이경찬 :) 2023. 3. 14. 16:45

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

 

프로그래머스

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

programmers.co.kr

실행코드

from collections import deque


def solution(maps):
    answer = -1
    row = len(maps)
    col = len(maps[0])
    lever = True
    # S의 위치 파악
    visited = [[False] * col for _ in range(row)]
    for i in range(len(maps)):
        for j in range(len(maps[i])):
            if maps[i][j] == "S":
                start_row = i
                start_col = j
                break
    delta = [(1,0),(-1,0),(0,1),(0,-1)]
    
    queue = deque()
    queue.append((start_row,start_col,0))
    # 먼저 레버 당기기 E찾기
    le_row,le_col,le_len = 0 , 0 , 0
    while queue:
        cur_r,cur_c,cur_len = queue.popleft()
        # 레버 L을 찾았을때
        if maps[cur_r][cur_c] == "L":
            le_row,le_col,le_len = cur_r,cur_c, cur_len
            lever = False
            break
        for dr , dc in delta:
            next_r = cur_r + dr
            next_c = cur_c + dc
            if next_r >= 0 and next_r < row and next_c >= 0 and next_c < col:
                if maps[next_r][next_c] != "X" and not visited[next_r][next_c]:
                    queue.append((next_r, next_c, cur_len + 1))
                    visited[next_r][next_c] = True
    # 레버가 없을경우 바로 -1 리턴
    if lever:
        return -1
    #방문 초기화
    visited2 = [[False] * col for _ in range(row)]
    #레버 위치에서 다시 시작
    queue2 = deque()
    queue2.append((le_row,le_col,le_len))
    while queue2:
        cur_r,cur_c,cur_len = queue2.popleft()
        #종료지점
        if maps[cur_r][cur_c] == "E":
            answer = cur_len
            break
        for dr, dc in delta:
            next_r = cur_r + dr
            next_c = cur_c + dc
            if next_r >= 0 and next_r < row and next_c >= 0 and next_c < col:
                if maps[next_r][next_c] != "X" and not visited2[next_r][next_c]:
                    queue2.append((next_r, next_c, cur_len + 1))
                    visited2[next_r][next_c] = True  

    return answer

코드 풀이:

먼저 제한사랑에서 maps의 길이가 5~100 이라서 O(n^2)까지의 시간복잡도를 사용해서 풀 수 있음을 알았습니다.

1. 먼저 이중 for문을 사용하여 S의 위치를 찾았습니다(시간복잡도가능)

2. 레버의 위치를 BFS 를 사용하여 찾아 주었습니다.

3. 여기서 레버를 찾지 못했다면 바로 -1을 return을 해 주었습니다.

4. 다시 큐를 선언해주고 이번에는 레버의 위치에서 E를 찾는 BFS를 사용해 주었습니다.

 

두번의BFS를 활용한 풀이를 하였습니다.