1631. Path With Minimum Effort (dijkstra
้้กๆไธ็ดๅธถ่ effort from start to end
ๆไปฅไธญ้่ฆๆดๆฐๆ, ่ฆๆๅคง็(origin effort and new effort)
ไฝๆๅบ pq ๆ, ่ฆๆๅฐ็, ้ๆจฃๆๅพๆๆๆฏ min effort
time: O(m*n * log(m*n))
space: O(m*n) // efftor matrix
use Dijkstra's algo
class Solution {
public int minimumEffortPath(int[][] heights) {
int m = heights.length;
int n = heights[0].length;
int effort[][] = new int[m][n];
for (int i = 0; i < m ; i++) {
Arrays.fill(effort[i], Integer.MAX_VALUE);
}
PriorityQueue<int[]> pq = new PriorityQueue<>(Comparator.comparingInt(a -> a[0]));
pq.offer(new int[]{0, 0, 0});
while (!pq.isEmpty()) {
int min[] = pq.poll();
int dist = min[0];
int row = min[1];
int col = min[2];
if (dist > effort[row][col]) { // prunig
continue;
}
if (row == m - 1 && col == n - 1) {
return dist;
}
int dir[][] = new int[][]{{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
for (int d[] : dir) {
int newRow = row + d[0];
int newCol = col + d[1];
if (newRow >= 0 && newRow < m && newCol >= 0 && newCol < n) {
// notie here
int newDist = Math.max(dist, Math.abs(heights[newRow][newCol] - heights[row][col]));
if (newDist < effort[newRow][newCol]) {
effort[newRow][newCol] = newDist;
pq.offer(new int[]{newDist, newRow, newCol});
}
}
}
}
return 0;
}
}
use a class to hold pq's data
class Solution {
private static final int[][] DIRS = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
class State {
int x;
int y;
int dist;
State(int x, int y, int dist) {
this.x = x;
this.y = y;
this.dist = dist;
}
}
public int minimumEffortPath(int[][] heights) {
int m = heights.length;
int n = heights[0].length;
Queue<State> pq = new PriorityQueue<>((a, b) -> a.dist - b.dist);
pq.offer(new State(0, 0, 0));
int[][] visited = new int[m][n];
for (int i = 0; i < m; i++) {
Arrays.fill(visited[i], Integer.MAX_VALUE);
}
while (!pq.isEmpty()) {
State cur = pq.poll();
int x = cur.x;
int y = cur.y;
int dist = cur.dist;
if (dist > visited[x][y]) {
continue;
}
if (x == m-1 && y == n-1) {
return dist;
}
for (int[] dir : DIRS) {
int newX = x + dir[0];
int newY = y + dir[1];
if (!isValid(heights, newX, newY)) {
continue;
}
// max (dist, diff)
int newDist = Math.max(dist, Math.abs(heights[x][y] - heights[newX][newY]));
if (newDist < visited[newX][newY]) {
visited[newX][newY] = newDist;
pq.offer(new State(newX, newY, newDist));
}
}
}
return 0;
}
private boolean isValid(int[][] heights, int x, int y) {
int m = heights.length;
int n = heights[0].length;
return x >= 0 && x < m && y >= 0 && y < n;
}
}
/*
A route's effort is the maximum absolute difference in heights between two consecutive cells of the route.
so effort is cell to cell's diff (maximum absolute difference)
cal the smallest effort
minimum effort required to travel from the top-left cell to the bottom-right cell.
so start: (0, 0)
end : (m-1, n-1)
effort: abs(cur x, y - next x, y)
pq: (x, y, effort)
update dist = min(dist, effor)
(0, 0, 0)
[x][y] = 1
(0, 1, 1) => choose this, dist = 1
if (newDist < effor[][]) {
efforp[][] = newDist;
}
(1, 0, 2)
*/
new version
```java
class Solution {
private static final int[][] DIRECTIONS = {{0,1}, {1, 0}, {0, -1}, {-1, 0}};
class State {
int x;
int y;
int effort;
State(int x, int y, int effort) {
this.x = x;
this.y = y;
this.effort = effort;
}
}
public int minimumEffortPath(int[][] heights) {
int m = heights.length;
int n = heights[0].length;
int[][] effortTo = new int[m][n];
for (int i = 0; i < m; i++) {
Arrays.fill(effortTo[i], Integer.MAX_VALUE);
}
effortTo[0][0] = 0; // mark start effor = 0
Queue<State> pq = new PriorityQueue<>((a, b) -> a.effort - b.effort);
pq.offer(new State(0, 0, 0));
while (!pq.isEmpty()) {
State currState = pq.poll();
if (currState.x == m-1 && currState.y == n-1) {
return currState.effort;
}
for (int[] dir : DIRECTIONS) {
int nextX = currState.x + dir[0];
int nextY = currState.y + dir[1];
if (nextX >= 0 && nextX < m && nextY >= 0 && nextY < n) {
int newEffort = Math.max(
currState.effort,
Math.abs(heights[nextX][nextY] - heights[currState.x][currState.y])
);
if (effortTo[nextX][nextY] > newEffort) {
effortTo[nextX][nextY] = newEffort;
pq.offer(new State(nextX, nextY, newEffort));
}
}
}
}
return -1;
}
}
/*
effort, if new curr to next effort < existing effort in nodes
use Dikstra to maintain ""min effort in the path""
-> keep going, add to queue
A route's effort is the maximum ""absolute"" difference in heights between two consecutive cells of the route.
*/
```
Previous499. The Maze III (spfa, dijkstraNext1368. Minimum Cost to Make at Least One Valid Path in a Grid
Last updated