499. The Maze III (spfa, dijkstra

this is good to read

https://leetcode.com/problems/the-maze-iii/discuss/1349818/Java-PriorityQueue-and-BFS

T: O(mn)
S: O(mn)
class Solution {
    int[][] dirs = {{-1,0},{0,1},{1,0},{0,-1}};
    String[] dirsStr = {"u","r","d","l"};
    class State implements Comparable<State>{
        int x;
        int y;
        int dist;
        String path;
        State(int x, int y, int dist, String path) {
            this.x = x;
            this.y = y;
            this.dist = dist;
            this.path = path;
        }
        State(int x, int y) {
            this.x = x;
            this.y = y;
            this.dist = Integer.MAX_VALUE;
            this.path = "";
        }
        public int compareTo(State p) {
            return this.dist == p.dist ? this.path.compareTo(p.path) : this.dist - p.dist;
        }
    }

    public String findShortestWay(int[][] maze, int[] ball, int[] hole) {
        int m = maze.length;
        int n = maze[0].length;

        
        State[][] dist = new State[m][n];
        for (int i = 0; i < m * n; i++) {
            dist[i / n][i % n] = new State(i / n, i % n);
        }
//         dist[ball[0]][ball[1]] = new State(ball[0], ball[1], 0, ""); dont need, why

        PriorityQueue<State> queue = new PriorityQueue<>(); // using priority queue
        queue.offer(new State(ball[0], ball[1], 0, ""));
        
        while (!queue.isEmpty()) {
            State cur = queue.poll();
            
            if (dist[cur.x][cur.y].compareTo(cur) <= 0) {
                continue;
            }
            dist[cur.x][cur.y] = cur;

            for (int i = 0; i < dirs.length; i++) {
                int[] dir = dirs[i];
                String newPath = dirsStr[i];

                int x = cur.x;
                int y = cur.y;
                int curDist = cur.dist;
                String curPath = cur.path;

                int steps = 0;
                // because when meet hole, while end, so we still need hole case
                while (isValid(maze, x, y, hole)) { 
                    x += dir[0];
                    y += dir[1];
                    steps++;
                }
                if (x != hole[0] || y != hole[1]) { // check the hole
                    x -= dir[0];
                    y -= dir[1];
                    steps--;
                }
                
                State next = new State(x, y, curDist + steps, curPath + newPath);
                queue.offer(next);
            }
        }
                
        return dist[hole[0]][hole[1]].dist == Integer.MAX_VALUE ? "impossible" : dist[hole[0]][hole[1]].path;
    }
    private boolean isValid(int[][] maze, int x, int y, int[] hole) {
        return x >= 0 && x < maze.length && y >= 0 && y < maze[0].length 
            && maze[x][y] == 0 && (x != hole[0] || y != hole[1]);
    }
}

dijkstra

Last updated

Was this helpful?