Problem
There is a dungeon with n x m
rooms arranged as a grid.
You are given a 2D array moveTime
of size n x m
, where moveTime[i][j]
represents the minimum time in seconds when you can start moving to that room. You start from the room (0, 0)
at time t = 0
and can move to an adjacent room. Moving between adjacent rooms takes one second for one move and two seconds for the next, alternating between the two.
Return the minimum time to reach the room (n - 1, m - 1)
.
Two rooms are adjacent if they share a common wall, either horizontally or vertically.
Examples
Example 1:
|
|
Example 2:
|
|
Example 3:
|
|
Constraints:
2 <= n == moveTime.length <= 750
2 <= m == moveTime[i].length <= 750
0 <= moveTime[i][j] <= 109
Solution
Method 1 - Dijkstra’s shortest path
The problem requires finding the minimum time to reach the bottom-right corner of a grid, while adhering to certain rules:
- Alternating movement cost: Moving between adjacent rooms alternates between
1 second
and2 seconds
. - Room availability: Each room has a minimum time (
moveTime[i][j]
) before it can be entered.- Delayed entry logic: If you arrive at a room before its
moveTime
, you must wait until the room becomes accessible.
- Delayed entry logic: If you arrive at a room before its
- Shortest path: Since adjacent rooms are connected, the problem resembles finding the shortest path in a weighted graph.
Approach
To solve this problem, we use a modified Dijkstra’s algorithm because:
- It handles weighted paths.
- It ensures that we process rooms in increasing order of time to reach them.
Steps
-
Start from
(0, 0)
attime = 0
:- Begin at the top-left room and initialise its arrival time to
0
.
- Begin at the top-left room and initialise its arrival time to
-
Tracking the alternating movement cost:
- Movement between rooms alternates between taking
1 second
and2 seconds
. - Keep track of the current movement cost (
step_cost
) as you explore rooms.
- Movement between rooms alternates between taking
-
Using a priority queue:
- Priority queue stores rooms to explore, prioritising those that can be reached sooner (lowest
arrival time
). - Each room’s priority queue entry includes:
- Current time (
t
of arrival). - Current position (
x
,y
). - Current movement cost (
step_cost
).
- Current time (
- Priority queue stores rooms to explore, prioritising those that can be reached sooner (lowest
-
Wait logic for room availability:
- When attempting to enter a room
(i, j)
:- Compute the wait time:
max(0, moveTime[i][j] - current_time)
. - Account for this wait in the total time spent.
- Compute the wait time:
- When attempting to enter a room
-
Optimality check:
- Maintain a matrix (
arrivalTime
) to store the earliest known time to reach each room. If you find a better (earlier) time for a room, update it and process it.
- Maintain a matrix (
-
Update movement cost:
- After moving to a room, alternate the step cost (
1 second
↔2 seconds
) before exploring further.
- After moving to a room, alternate the step cost (
-
Termination:
- Stop and return the time as soon as you reach the bottom-right room (
(n-1, m-1)
).
- Stop and return the time as soon as you reach the bottom-right room (
Code
|
|
|
|
Complexity
- ⏰ Time complexity:
O(n * m * log(n * m))
. The priority queue requireslog(n * m)
operation for each of then * m
possible cells. - 🧺 Space complexity:
O(n + m)
. Accounts for theminimumArrivalTime
matrix and priority queue.