DFS로 처음에 문제를 풀려고 했다.
근데 아무리 해도 시간초과가 나서 한참을 고민했다. (분명 최단거리 문제를 DFS로 풀수있는데 왜 안될까 ?)
결국 정답을 보고 나의 문제점을 알 수 있었다.
import java.util.Arrays;
class Solution {
int ROW, COL;
int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int[][] visited;
char[][] map;
int[] start, goal;
private int answer;
public int solution(String[] board) {
answer = Integer.MAX_VALUE;
ROW = board.length;
COL = board[0].length();
visited = new int[ROW][COL];
for (int[] ints : visited) {
Arrays.fill(ints, Integer.MAX_VALUE);
}
this.map = new char[ROW][COL];
for (int r = 0; r < ROW; r++) {
for (int c = 0; c < COL; c++) {
char ch = board[r].charAt(c);
map[r][c] = ch;
if (ch == 'R') {
start = new int[]{r, c};
} else if (ch == 'G') {
goal = new int[]{r, c};
}
}
}
visited[start[0]][start[1]] = 0;
dfs(start[0], start[1], 0);
return answer == Integer.MAX_VALUE ? -1 : answer;
}
private void dfs(int curRow, int curCol, int cnt) {
if (map[curRow][curCol] == 'G') {
answer = Math.min(answer, cnt);
return;
}
for (int direction = 0; direction < directions.length; direction++) {
int[] nextRowCol = goStraight(curRow, curCol, direction);
int nextRow = nextRowCol[0];
int nextCol = nextRowCol[1];
if (visited[nextRow][nextCol] <= cnt + 1) {
continue;
}
visited[nextRow][nextCol] = cnt + 1;
dfs(nextRow, nextCol, cnt + 1);
}
}
private int[] goStraight(int curRow, int curCol, int direction) {
while (true) {
int nextRow = curRow + directions[direction][0];
int nextCol = curCol + directions[direction][1];
if (isOutOfMap(nextRow, nextCol) || map[nextRow][nextCol] == 'D') {
break;
}
curRow += directions[direction][0];
curCol += directions[direction][1];
}
return new int[]{curRow, curCol};
}
private boolean isOutOfMap(int nextRow, int nextCol) {
return nextRow < 0 || nextRow >= ROW || nextCol < 0 || nextCol >= COL;
}
}
import java.util.ArrayDeque;
import java.util.Deque;
class Solution {
int ROW, COL;
int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
boolean[][] visited;
char[][] map;
int[] start, goal;
private int answer;
public int solution(String[] board) {
answer = Integer.MAX_VALUE;
ROW = board.length;
COL = board[0].length();
visited = new boolean[ROW][COL];
this.map = new char[ROW][COL];
for (int r = 0; r < ROW; r++) {
for (int c = 0; c < COL; c++) {
char ch = board[r].charAt(c);
map[r][c] = ch;
if (ch == 'R') {
start = new int[]{r, c};
} else if (ch == 'G') {
goal = new int[]{r, c};
}
}
}
visited[start[0]][start[1]] = true;
bfs(start[0], start[1], 0);
return answer == Integer.MAX_VALUE ? -1 : answer;
}
private void bfs(int curRow, int curCol, int cnt) {
Deque<int[]> deque = new ArrayDeque<>();
deque.add(new int[]{curRow, curCol, cnt});
while (!deque.isEmpty()) {
int[] cur = deque.poll();
int cR = cur[0];
int cC = cur[1];
int cCnt = cur[2];
if (cR == goal[0] && cC == goal[1]) {
answer = Math.min(answer, cCnt);
return;
}
for (int direction = 0; direction < directions.length; direction++) {
int[] nextRowCol = goStraight(cR, cC, direction);
int nextRow = nextRowCol[0];
int nextCol = nextRowCol[1];
if (visited[nextRow][nextCol]) {
continue;
}
visited[nextRow][nextCol] = true;
deque.add(new int[]{nextRow, nextCol, cCnt + 1});
}
}
}
private int[] goStraight(int curRow, int curCol, int direction) {
while (true) {
int nextRow = curRow + directions[direction][0];
int nextCol = curCol + directions[direction][1];
if (isOutOfMap(nextRow, nextCol) || map[nextRow][nextCol] == 'D') {
break;
}
curRow += directions[direction][0];
curCol += directions[direction][1];
}
return new int[]{curRow, curCol};
}
private boolean isOutOfMap(int nextRow, int nextCol) {
return nextRow < 0 || nextRow >= ROW || nextCol < 0 || nextCol >= COL;
}
}