leetcode困难1293网格中的最短路径
Posted qq_40707462
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode困难1293网格中的最短路径相关的知识,希望对你有一定的参考价值。
给你一个 m * n 的网格,其中每个单元格不是 0(空)就是 1(障碍物)。每一步,您都可以在空白单元格中上、下、左、右移动。
如果您 最多 可以消除 k 个障碍物,请找出从左上角 (0, 0) 到右下角 (m-1, n-1) 的最短路径,并返回通过该路径所需的步数。如果找不到这样的路径,则返回 -1。
示例 1:
输入:
grid =
[[0,0,0],
[1,1,0],
[0,0,0],
[0,1,1],
[0,0,0]],
k = 1
输出:6
解释:
不消除任何障碍的最短路径是 10。
消除位置 (3,2) 处的障碍后,最短路径是 6 。该路径是:
(0,0) -> (0,1) -> (0,2) -> (1,2) -> (2,2) -> (3,2) -> (4,2).
思路:bfs
- 传统BFS:如果点A已经在visited里,那我们就不会第二次加入点A
- 本题:如果点A已经在visited里,但是这次我们到点A的路径上碰到的障碍物比上次少,那我们要把点A加入queue
visited数组记录剩余消除障碍物次数,越多越好。要先消灭障碍物(visited-1),再比较,所以visited要初始化为 -1 ,若visited-1=0,大于当前值 -1,也是合法的,更新并加入队列
- 对于其他路径到达此点,且剩余消除障碍物次数小于等于当前值 —— 剪枝
- 对于其他路径到达此点,且剩余消除障碍物次数大于当前值 —— 取代并入队
class Solution
public int shortestPath(int[][] grid, int k)
int m=grid.length,n=grid[0].length;
int[] dx = new int[]0, 1, -1, 0;
int[] dy = new int[]1, 0, 0, -1;
int[][]visited=new int[m][n];
for (int i = 0; i < m; i++) //visited初始化为-1
Arrays.fill(visited[i], -1);
List<int[]>que=new ArrayList<>();
que.add(new int[]0,0,k);
visited[0][0]=k;
int step=0;
while(!que.isEmpty())
int size=que.size();
while(size-->0)//剩余次数必须在同一层级比较
int[]temp=que.remove(0);
int i=temp[0],j=temp[1],r=temp[2];
// 搜索到目标节点直接返回结果,按层级来说就是最短步数
if(i==m-1 && j==n-1) return step;
for(int d=0;d<4;d++)
int x=dx[d]+i;
int y=dy[d]+j;
if(x<0||x>=m||y<0||y>=n) continue;
//判断是否是障碍物
int newR = r + (grid[x][y] == 1 ? -1 : 0);
if(newR > visited[x][y])
visited[x][y] = newR;//更新同一位置的r,保持最小
que.add(new int[]x, y, newR);
step++;
return -1;
以上是关于leetcode困难1293网格中的最短路径的主要内容,如果未能解决你的问题,请参考以下文章
[JavaScript 刷题] 搜索 - 计算在网格中从原点到特定点的最短路径长度 Leetcode 1091
⭐算法入门⭐《动态规划 - 状态压缩DP》困难01 —— LeetCode 847. 访问所有节点的最短路径