본문 바로가기
알고리즘 문제/Java

[프로그래머스/Java] 미로 탈출

by 현장 2026. 5. 7.

-Code

import java.util.*;

class Solution {
    static class PosInfo {
        int row, col, time;

        public PosInfo (int row, int col, int time) {
            this.row = row;
            this.col = col;
            this.time = time;
        }
    }
    static int rowSize;
    static int colSize;
    static char[][] mapArr;
    static boolean[][] visited;
    // 이동 방향 셋팅
    static int[] dRow = {-1, 1, 0, 0};
    static int[] dCol = {0, 0, -1, 1};

    public int solution(String[] maps) {
        rowSize = maps.length;
        colSize = maps[0].length();
        // visited 셋팅
        visited = new boolean[rowSize][colSize];
        // 시작점 찾으면서 배열에 저장
        PosInfo start = null, lever = null;
        mapArr = new char[rowSize][colSize];
        for (int r = 0; r < rowSize; r++) {
            for (int c = 0; c < colSize; c++) {
                mapArr[r][c] = maps[r].charAt(c);
                if (mapArr[r][c] == 'S') {
                    start = new PosInfo(r, c, 0);
                }
            }
        }
        // visited 셋팅
        visited = new boolean[rowSize][colSize];
        // 레버까지 거리 구하기
        PosInfo leverInfo = getTargetTime(start, 'L');
        if (leverInfo == null) return -1;
        // visited 초기화
        visited = new boolean[rowSize][colSize];
        // 탈출 위치까지 거리 계산
        PosInfo exitTime = getTargetTime(leverInfo, 'E');
        if (exitTime == null) return -1;
        // 총 거리 반환
        return exitTime.time;
    }

    private PosInfo getTargetTime(PosInfo start, char target) {
        // 시작점 덱에 추가 및 방문 처리
        Deque<PosInfo> posDeq = new ArrayDeque<>();
        posDeq.addLast(start);
        visited[start.row][start.col] = true;
        // 탐색
        while (!posDeq.isEmpty()) {
            PosInfo now = posDeq.pollFirst();
            // 목적지에 버튼을 누르고 도착했으면 값 반환
            if (mapArr[now.row][now.col] == target) {
                return now;
            }
            // 4방향 검사
            for (int i = 0; i < 4; i++) {
                int nextRow = now.row + dRow[i];
                int nextCol = now.col + dCol[i];
                // 이동 가능하고 벽이 아닌 경우 덱에 넣기
                if (isMove(nextRow, nextCol) 
                        && !visited[nextRow][nextCol] 
                        && mapArr[nextRow][nextCol] != 'X') {
                    visited[nextRow][nextCol] = true;
                    PosInfo next = new PosInfo(nextRow, nextCol, now.time + 1);
                    posDeq.addLast(next);
                }
            }
        }
        return null;
    }
    // 이동 가능한지 확인
    private boolean isMove(int row, int col) {
        return (0 <= row && row < rowSize) && (0 <= col && col < colSize);
    }
}

BFS로 방향은 잘 잡았으나 버튼을 누르는 boolean을 넣어서 처리하려다가 visited 처리에서 문자가 생겨서 진행이 되지 않았습니다. 그래서 조금 찾아보니 레버까지 시간과 탈출까지 시간을 각각 따로 계산하여 풀면 된다는 힌트를 얻고 해결했습니다.