Java PriorityQueue with Comments
\nclass Solution {\n    private static final int[][] DIRS = new int[][] { { 1, 0 }, { -1, 0}, { 0, 1 }, { 0, -1 } };\n    public int minimumTime(int[][] grid) {
```\nclass Solution {\n    private static final int[][] DIRS = new int[][] { { 1, 0 }, { -1, 0}, { 0, 1 }, { 0, -1 } };\n    public int minimumTime(int[][] grid) {\n        if (grid[0][1] > 1 && grid[1][0] > 1) {\n            return -1;\n        }\n        \n        int m = grid.length;\n        int n = grid[0].length;\n        \n        PriorityQueue<int[]> heap = new PriorityQueue<>((a, b) -> a[2] - b[2]);\n        heap.offer(new int[] { 0, 0, 0 }); // row, col, time\n        \n        boolean[][] visited = new boolean[m][n];\n        \n        while (!heap.isEmpty()) {\n            int[] entry = heap.poll();\n            int row = entry[0];\n            int col = entry[1];\n            int time = entry[2];\n            if (row == m - 1 && col == n - 1) {\n                return time;\n            }\n            if (visited[row][col]) {\n                continue;\n            }\n            visited[row][col] = true;\n                \n            for (int[] dir : DIRS) {\n                int r = row + dir[0];\n                int c = col + dir[1];\n                if (r < 0 || r == m || c < 0 || c == n || visited[r][c]) {\n                    continue;\n                }\n                \n                if (grid[r][c] <= time + 1) {\n                    // if it is possible to move to neighbor, do it\n                    heap.offer(new int[] { r, c, time + 1 });\n                } else {\n                    // If we cant move to neighbor yet, we can hop to the previous cell\n                    // and back to current cell as many times as we need to until\n                    // sufficient time has passed.\n                    // The trick here is that if the difference between the current time\n                    // and the time we need is even, we will arrive back at the current cell\n                    // 1 second "late" and so we will move to the neighbor 1 second after\n                    // the minimum neighbor time.\n                    int diff = grid[r][c] - time;\n                    if (diff % 2 == 1) {\n                        heap.offer(new int[] { r, c, grid[r][c] });\n                    } else {\n                        heap.offer(new int[] { r, c, grid[r][c] + 1 });\n                    }\n                }\n            }\n        }\n        return -1; // will never reach here\n    }\n}\n```
['Heap (Priority Queue)', 'Java']