🔥Beats 100 % 🔥 | ✔️ Optimized Dijkstra's Algorithm ✔️ | O(m * nlog(m * n))
Intuition\nThis solution uses a priority queue min-heap to efficiently explore the grid in increasing order of time, ensuring the optimal path is chosen to reac
# Intuition\nThis solution uses a **priority queue** `min-heap` to efficiently explore the `grid` in increasing order of time, ensuring the **optimal path** is chosen to reach the target cell at the **bottom-right corner** `rows - 1` `cols - 1`.\n\n# Approach\n`Step 1` **Early Exit Condition**\n- If both possible moves from the starting position `(0, 0)` **either down or right** require more than **1 second** `grid[0][1] > 1 && grid[1][0] > 1` then the traversal is impossible from the start. The function `returns -1` immediately.\n\n`Step 2` **Initialization**\n- **Directions Array (MOVES) :** Specifies the four possible movement directions: up `({-1, 0})`, right `({0, 1})`, down `({1, 0})`, and left `({0, -1})`. This is used for exploring neighboring cells.\n- **Priority Queue :** The **priority queue** stores cells with the format `{time, row, col}`, where time is the current time to reach a given cell. \n- **Seen Array :** Tracks whether a cell has been visited to avoid **reprocessing** and **infinite loops**.\n\n`Step 3` **Start BFS-like Search**\n- **Add the starting Cell :** `0, 0` to the **priority queue** with the time set to 0: `pq.offer(new int[]{0, 0, 0})`. \n- **Mark it as visited :** `seen[0][0] = true`.\n\n`Step 4` **Explore Cells**\n- **Pop the Cell with Minimum Time :** Main loop continues as long as the priority queue is not empty. It processes the cell with the smallest time.\n- **For Each Direction :** For each direction in the `MOVES` array `(up, right, down, left)`, compute the `newRow` and `newCol` by applying the direction to the current cell\'s coordinates.\n- **Boundary Check :** Skip cells that are out of bounds or already visited.\n\n`Step 5` **Calculate New Time for Neighbors**\n- **Compute New Time :** Start with the `newTime = time + 1` \n- **Check Wait Time :** If moving to the next cell requires more time  `grid[newRow][newCol] > newTime`. \n    - **Calculate the wait time :** This ensures that the wait time is adjusted based on the current time and the constraints in the grid.\n    - `wait = ((grid[newRow][newCol] - newTime + 1) / 2) * 2`. \n    \n- **Update Time :** Add wait time to the new time, so `newTime += wait`.\n\n`Step 6` **Reaching the Target**\n- If the current cell is the **bottom-right corner** `rows - 1, cols - 1`, return the `newTime` as the answer since we\'ve reached the destination.\n\n`Step 7` **Push the Neighbor to the Priority Queue**\n- If neighbor is valid and hasn\'t been visited yet, mark visited and push updated time and coordinates to the `priority queue`.\n\n`Step 8` **Termination**\n- If the priority queue is exhausted and the target cell hasn\'t been reached `return -1`, indicating that it\'s impossible to reach the **bottom-right corner.**\n\n# Complexity\n- Time complexity: $$O(M * Nlog(M * N))$$\n- Space complexity : $$O(M * N)$$\n\n# Code\n```java []\nclass Solution\n{\n    private static final int[][] MOVES = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};  // Directions for movement (up, right, down, left)\n    \n    public int minimumTime(int[][] grid)\n    {\n        int rows = grid.length;\n        int cols = grid[0].length;\n\n        // Step 1: If both initial moves are blocked, return -1\n        if (grid[0][1] > 1 && grid[1][0] > 1)\n        {\n            return -1;  // Both right and down from (0, 0) are not possible\n        }\n\n        // Step 2: Initialize the priority queue and the visited array\n        PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]);  // Min-heap based on time\n        boolean[][] seen = new boolean[rows][cols];\n\n        pq.offer(new int[]{0, 0, 0}); // Start with (0, 0) at time 0\n        seen[0][0] = true;\n\n        // Step 3: BFS-like traversal using priority queue\n        while (!pq.isEmpty())\n        {\n            int[] curr = pq.poll(); // Get the current cell with the smallest time\n            int time = curr[0];\n            int row = curr[1];\n            int col = curr[2];\n\n            // Step 4: Explore all four directions\n            for (int[] dir : MOVES)\n            {\n                int newRow = row + dir[0];\n                int newCol = col + dir[1];\n\n                // Step 5: Skip invalid cells (out of bounds or already visited)\n                if (newRow < 0 || newRow >= rows || newCol < 0 || newCol >= cols || seen[newRow][newCol])\n                {\n                    continue;\n                }\n\n                // Step 6: Calculate the time to move to the next cell\n                int newTime = time + 1;\n                if (grid[newRow][newCol] > newTime)\n                {\n                    int wait = ((grid[newRow][newCol] - newTime + 1) / 2) * 2;  // Wait if necessary\n                    newTime += wait;\n                }\n\n                // Step 7: If we reached the target cell, return the current time\n                if (newRow == rows - 1 && newCol == cols - 1)\n                {\n                    return newTime;\n                }\n\n                // Step 8: Mark the cell as visited and add it to the priority queue\n                seen[newRow][newCol] = true;\n                pq.offer(new int[]{newTime, newRow, newCol});\n            }\n        }\n\n        // Step 9: If no path is found, return -1\n        return -1;\n    }\n}\n```
['Array', 'Breadth-First Search', 'Graph', 'Queue', 'Heap (Priority Queue)', 'Matrix', 'Shortest Path', 'Java']