diff --git a/java/nearest-exit-from-entrance-in-maze.java b/java/nearest-exit-from-entrance-in-maze.java new file mode 100644 index 0000000..1352074 --- /dev/null +++ b/java/nearest-exit-from-entrance-in-maze.java @@ -0,0 +1,53 @@ +import java.util.ArrayDeque; + +class Solution { + private static final int[][] DIRECTIONS = + new int[][] { + new int[] {0, 1}, + new int[] {0, -1}, + new int[] {1, 0}, + new int[] {-1, 0}, + }; + + private record Cell(int distance, int y, int x) { + public boolean onEdge(int width, int height) { + return y == 0 || y == height - 1 || x == 0 || x == width - 1; + } + + public boolean inBounds(int width, int height) { + return y >= 0 && y < height && x >= 0 && x < width; + } + } + + public int nearestExit(char[][] maze, int[] entrance) { + int width = maze[0].length, height = maze.length; + + var visited = new boolean[height][width]; + + var q = new ArrayDeque(); + q.offer(new Cell(0, entrance[0], entrance[1])); + visited[entrance[0]][entrance[1]] = true; + + while (!q.isEmpty()) { + var c = q.poll(); + + if (c.onEdge(width, height) && c.distance() > 0) { + return c.distance(); + } + + for (var d : DIRECTIONS) { + int dy = d[0], dx = d[1]; + + var n = new Cell(c.distance() + 1, c.y() + dy, c.x() + dx); + if (!n.inBounds(width, height) || maze[n.y()][n.x()] != '.' || visited[n.y()][n.x()]) { + continue; + } + + q.offer(n); + visited[n.y()][n.x()] = true; + } + } + + return -1; + } +}