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. 访问所有节点的最短路径

LeetCode 0864. 获取所有钥匙的最短路径:广搜 + 状压

访问某些节点的网格图的最短路径算法

VTK计算网格模型上的最短路径

用Dijkstra算法求最短路径的MATLAB程序