시작 위치인 R 위치에서 목적 위치인 G로만 가면 되는 문제인줄 알았다. 하지만 예시를 보니 그런 문제가 아니었다... 다시 문제를 읽어보니 문제가 이해가 되지 않았다. 이래서 책을 많이 읽으라고 하는 것 같다... 다시 집중해서 읽어보니 목적지 위치를 거치면 로직이 끝나는 것이 아니고 로봇이 멈춘 위치가 목적지 위치여야 하는 것이었다.
멈추는 조건은 벽에 부딪히거나 즉 배열 범위를 벗어나거나 장애물 위치인 D 위치에 도달하면 멈추고 방향을 바꿔 또 다시 벽이나 장애물 위치에 도달하면 멈추고 방향을 바꾸는 방식이다. 이와 같은 조건을 제외하곤 일반 경로 탐색과 유사하다.
import java.util.*;
class Solution {
static class Robot{
int x, y, cnt;
Robot(int x, int y, int cnt){
this.x = x;
this.y = y;
this.cnt = cnt;
}
}
static int[] dx = {-1, 1, 0, 0};
static int[] dy = {0, 0, -1, 1};
static int startX, startY;
static int endX, endY;
static char[][] map;
static boolean[][] visited;
static int cnt;
static public int solution(String[] board) {
int answer = -1;
int row = board.length;
int height = board[0].length();
Queue<Robot> q = new ArrayDeque<>();
visited = new boolean[row][height];
map = new char[row][height];
// 1차원 String 배열을 char[][] 배열로 변환하고 시작 위치와 목적 위치 좌표 값 저장
for(int i=0; i<board.length; i++){
for(int j=0; j<board[i].length(); j++){
map[i][j] = board[i].charAt(j);
if(board[i].substring(j, j+1).equals("R")){
startX = i;
startY = j;
}
if(board[i].substring(j, j+1).equals("G")){
endX = i;
endY = j;
}
}
}
q.add(new Robot(startX, startY, 0));
while(!q.isEmpty()) {
Robot cur = q.poll();
int x = cur.x;
int y = cur.y;
int cnt = cur.cnt;
visited[x][y] = true;
if(x == endX && y == endY) {
return cnt;
}
for(int k=0; k<4; k++){
int nx = x + dx[k];
int ny = y + dy[k];
// 벽이나 장애물 위치가 나올 때까지 해당 방향으로 전진
while (nx>=0 && ny >= 0 && nx < row && ny < height && map[nx][ny] != 'D'){
nx += dx[k];
ny += dy[k];
}
nx -= dx[k];
ny -= dy[k];
// 방문했던 위치거나 바로 장애물이나 벽이 나오는 위치 일 때
if(visited[nx][ny] || (x == nx && y == ny)) continue;
visited[nx][ny] = true;
q.add(new Robot(nx, ny, cnt+1));
}
}
return answer;
}
}
while (nx>=0 && ny >= 0 && nx < row && ny < height && map[nx][ny] != 'D')
코드를 처음에 while(map[nx][ny] == 'D' || nx<0 || ny < 0 || nx> row || ny > height)
로 작성했을 때 map[nx][ny] == 'D' 부분을 먼저 적는 것이 아닌 범위를 벗어나는지 여부부터 판별하지 않으면 범위를 벗어난 배열 값을 찾아 ArrayIndexOut 에러가 발생한다. 코드의 순서에 따라 로직이 완전히 바뀐다는 것을 항상 인지하며 코드를 작성해야겠다.....