Minimax Dijkstra
Time O(mn log(mn)) Space O(mn)effort[0][0] = 0. Pop the smallest effort; for each neighbour, candidate = max(effort, |Δh|); relax if smaller. Stop when the corner is popped.
import java.util.*;
class Solution {
public int minimumEffortPath(int[][] heights) {
int m = heights.length, n = heights[0].length;
int[][] best = new int[m][n];
for (int[] row : best) Arrays.fill(row, Integer.MAX_VALUE);
best[0][0] = 0;
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> Integer.compare(a[0], b[0]));
pq.offer(new int[]{0, 0, 0});
int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
while (!pq.isEmpty()) {
int[] t = pq.poll();
int e = t[0], r = t[1], c = t[2];
if (r == m - 1 && c == n - 1) return e;
if (e > best[r][c]) continue;
for (int[] d : dirs) {
int nr = r + d[0], nc = c + d[1];
if (nr < 0 || nc < 0 || nr >= m || nc >= n) continue;
int ne = Math.max(e, Math.abs(heights[nr][nc] - heights[r][c]));
if (ne < best[nr][nc]) { best[nr][nc] = ne; pq.offer(new int[]{ne, nr, nc}); }
}
}
return 0;
}
}Verdict: The max-combine keeps the greedy argument valid.