This problem reduces to finding a path from the top-left corner to the bottom-right corner where the maximum elevation along the path is as small as possible. The "time" framing is a distraction. You can traverse a cell at time t only if its elevation is at most t, so the least time to reach the destination equals the maximum elevation on the best path from (0,0) to (n-1, n-1). Among all paths, the best one is the path whose tallest cell is the shortest.
This is a minimax path problem. The cost of a path is not the sum of its cells (as in shortest path) but the single highest cell on it, and we want to minimize that value over all paths.
1 <= n <= 50 → The grid has at most 2,500 cells, small enough for an O(n^2 log n) solution.0 <= grid[i][j] < n^2 with all values unique → The elevations are a permutation of 0 to n^2-1. Since they are distinct and dense, we can map each elevation directly to its cell and process cells in elevation order without sorting. This drives the Union-Find approach.Checking a fixed answer is easy. Given a candidate value T, a path is reachable at time T if and only if there is a route from (0,0) to (n-1,n-1) using only cells with grid[i][j] <= T. That is a plain BFS reachability check.
Reachability is monotonic in T. If a path exists at time T, the same path exists at every T+1 and beyond, since raising the water level never removes a usable cell. So there is a single threshold below which no path exists and above which one always does, and that threshold is the answer. A monotonic yes/no predicate is the setup for binary search on the answer.
The search range runs from max(grid[0][0], grid[n-1][n-1]) (the start and end cells must be usable) up to n*n - 1 (the largest elevation). For each candidate T, run BFS to test feasibility.
low = max(grid[0][0], grid[n-1][n-1]) and high = n * n - 1.low < high:mid = (low + high) / 2.(0,0), only visiting cells where grid[i][j] <= mid.(n-1, n-1) is reachable, set high = mid.low = mid + 1.low.Binary search reruns a full BFS for every candidate threshold. The next approach finds the answer in a single traversal by always expanding the cell reachable with the smallest maximum elevation.
A priority queue solves this in one pass. The structure mirrors Dijkstra's algorithm, except the cost of a path is the maximum elevation along it rather than the sum of edge weights, so the heap key is that running maximum instead of a running sum.
Start at (0,0). The "distance" to any cell is the smallest possible maximum elevation on a path that reaches it. Each heap entry stores that running maximum together with the cell. When a neighbor (nr, nc) is reached from a cell whose path maximum is maxElev, the path maximum at the neighbor becomes max(maxElev, grid[nr][nc]). Always pop the entry with the smallest running maximum.
When (maxElev, r, c) is popped, maxElev is the minimum achievable path maximum to (r, c). The argument is the same as Dijkstra's: the popped key is the smallest in the heap, and every cell still unprocessed is reached through a path whose maximum is at least the popped key. Extending any such path can only keep or raise its maximum (taking max is monotone), so no later route can reach (r, c) more cheaply. The first time (n-1, n-1) is popped, its key is therefore the final answer.
(grid[0][0], 0, 0) onto a min-heap. Mark (0,0) as visited.(maxElevation, r, c) with the smallest max elevation.(r, c) is the destination (n-1, n-1), return maxElevation.(nr, nc):newMax = max(maxElevation, grid[nr][nc]).(newMax, nr, nc) onto the heap and mark it visited.The heap adds a log factor to each cell. The next approach drops it by processing cells in elevation order and connecting each new cell to its processed neighbors until the start and end join the same component.
Raise the water level from 0 to n^2-1. At each level exactly one new cell becomes available, because the elevations are distinct. The first level at which (0,0) and (n-1, n-1) belong to the same connected region of available cells is the answer.
Union-Find tracks those regions incrementally. Process cells in increasing elevation order. As each cell becomes available, union it with any of its four neighbors that are already available. After processing a cell, check whether the start and end share a root. The first elevation at which they do is the result. Because elevations form a dense permutation, the cell of a given elevation can be located in O(1) from a precomputed position array, so no separate sort is needed.
position array mapping each elevation t to its (row, col). Since elevations are a permutation of 0 to n^2-1, this replaces sorting.available initialized to all false.t from 0 to n^2-1:(r, c) = position[t] and mark it available.(r, c) with each adjacent cell that is already available.find(0) == find(n*n - 1), return t.