Shortest Path in a Grid with Obstacles Elimination

Given a m * n grid, where each cell is either 0 (empty) or 1 (obstacle). In one step, you can move up, down, left or right from and to an empty cell.

Return the minimum number of steps to walk from the upper left corner (0, 0) to the lower right corner (m-1, n-1) given that you can eliminate at most k obstacles. If it is not possible to find such walk return -1.

Example 1:

Input: 
grid = 
[[0,0,0],
 [1,1,0],
 [0,0,0],
 [0,1,1],
 [0,0,0]], 
k = 1
Output: 6
Explanation: 
The shortest path without eliminating any obstacle is 10. 
The shortest path with one obstacle elimination at position (3,2) is 6. Such path is (0,0) -> (0,1) -> (0,2) -> (1,2) -> (2,2) -> (3,2) -> (4,2)思路://为什么需要第三维度信息,是因为到x,y我可以以好几种方式到达,也就是不remove 1,
     //和remove多个1之后到达,虽然坐标一样,但是状态是不一样的
class Solution {
    class Node {
        public int x;
        public int y;
        public int usedk;
        public Node(int x, int y, int usedk) {
            this.x = x;
            this.y = y;
            this.usedk = usedk;
        }
    }
    
    public int shortestPath(int[][] grid, int k) {
        int m = grid.length; 
        int n = grid[0].length;
        Queue<Node> queue = new LinkedList<>();
        boolean[][][] visited = new boolean[m][n][k + 1];
        
        queue.offer(new Node(0, 0, k));
        visited[0][0][k] = true;
        int step = 0;
        
        int[][] dirs = new int[][]{{0,1},{0,-1},{-1,0},{1,0}};
        while(!queue.isEmpty()) {
            int size = queue.size();
            for(int i = 0; i < size; i++) {
                Node node = queue.poll();
                int x = node.x;
                int y = node.y;
                if(x == m - 1 && y == n - 1) {
                    return step;
                }
                for(int[] dir: dirs) {
                    int nx = x + dir[0];
                    int ny = y + dir[1];
                    // 注意这个nextk,必须在里面,因为每次move都必须从原来的node usedk出发;
                    int nextk = node.usedk;
                    if(0 <= nx && nx < m && 0 <= ny && ny < n) {
                        if(grid[nx][ny] == 1) {
                            nextk--;
                        }
                        
                        if(nextk >= 0 && !visited[nx][ny][nextk]) {
                         queue.offer(new Node(nx, ny, nextk));
                        visited[nx][ny][nextk] = true;
                        }
                    }
                }
            }
            step++;
        }
        return -1;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值