LeetCode: 1631. 最小体力消耗路径
二分查找思路
枚举最小的体力萧消耗值
如果 右下角可达, 那么就 减少 right 边界, 如果 右下角不可达, 那么增加 left 边界
AC Code
class Solution {
public int minimumEffortPath(int[][] h) {
// 二分,枚举最小的体力萧消耗值
int row = h.length, col = h[0].length;
int left = 0, right = (int)1e6;
int ans = 0;
// 方向数组
int[][] dir = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
while(left <= right) {
int mid = left + (right - left) / 2;
Queue<int[]> queue = new LinkedList<>();
// 二维 -> 一维
boolean[] vis = new boolean[row * col];
// 起点
queue.add(new int[]{0, 0});
vis[0] = true;
while(!queue.isEmpty()) {
int[] arr = queue.poll();
int x = arr[0], y = arr[1];
// 上下左右
for(int i = 0; i < 4; i++) {
int dx = arr[0] + dir[i][0];
int dy = arr[1] + dir[i][1];
// 合法且没有访问过
if(dx >= 0 && dy >= 0 && dx < row && dy < col &&
!vis[dx * col + dy] && Math.abs(h[dx][dy] - h[x][y]) <= mid) {
queue.add(new int[]{dx, dy});
vis[dx * col + dy] = true;
}
}
}
if(vis[row * col - 1]) {
ans = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return ans;
}
}