[leetcode]-1293 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.

思路:

BFS (Breadth First Search) 寬度優先搜索,使用隊列(queue)來實現:首先把根節點放到隊列中;每次從隊列的頭部取出一個元素,查看這個元素所有的下一級元素,把它們放到隊列的末尾;並把這個元素記爲它下一級元素的前驅;找到所要找的元素時結束程序;如果遍歷整個樹還沒有找到,結束程序。

本題中將寬度視爲所走的步數step:

1)開始時將(0,0)放入隊列中;

2)每次從隊列的頭部取出一個格子,查看所有它能走到的所有格子(上、下、左、右),加入到隊列的末尾;

3)當取出的元素爲(m-1,n-1)時,記錄步數並更新最小值;

4)直到隊列爲空。

本題重點:

判斷格子是否被訪問過,應該用x座標、y座標、剩餘obstacle數目三個維度,而不是僅僅x座標和y座標兩個維度。

代碼:

import java.util.LinkedList;
import java.util.Queue;

class ShortestPath{
    class Node{
        public int x, y, step, obstacle;
        public Node(int x, int y, int step, int obstacle){
            this.x = x;
            this.y = y;
            this.step = step;
            this.obstacle = obstacle;
        }
    }

    public int shortestPath(int[][] grid, int k) {
        //the min steps when arrive at (m-1,n-1)
        int count = -1;
        Queue<Node> list = new LinkedList();
        //boolean array to check when the grid is visited or not
        boolean[][][] visited = new boolean[grid.length][grid[0].length][k+1];
        for(int i =0; i < grid.length; ++i)
            for(int j = 0; j < grid[0].length; ++j)
                for(int h = 0; h < k+1; ++h)
                    visited[i][j][h] = false;
        //add (0,0) to the head of the queue
        list.add(new Node(0,0, 0,k-grid[0][0]));
        visited[0][0][k] = true;
        while(!list.isEmpty()){
            Node tmp = list.poll();
            //when arrive at (m-1,n-1)
            if(tmp.x == grid.length-1 && tmp.y == grid[0].length-1 
                    && tmp.obstacle >= 0){
                if(count == -1){
                    count = tmp.step;
                    System.out.println("arrive :" + count);
                }else if(tmp.step <= count){
                    count = tmp.step;
                    System.out.println("arrive :" + count);
                }
            }
            //four cases: left, right, up, down
            if(tmp.x-1 >= 0){
                int newk = tmp.obstacle-grid[tmp.x-1][tmp.y];
                if(newk >= 0 && visited[tmp.x-1][tmp.y][newk] == false) {
                    list.add(new Node(tmp.x - 1, tmp.y, tmp.step + 1, newk));
                    visited[tmp.x - 1][tmp.y][newk] = true;
                }
            }
            if(tmp.x +1 < grid.length ){
                int newk = tmp.obstacle-grid[tmp.x+1][tmp.y];
                if(newk >= 0 && visited[tmp.x+1][tmp.y][newk] == false) {
                    list.add(new Node(tmp.x+1, tmp.y, tmp.step + 1, newk));
                    visited[tmp.x+1][tmp.y][newk] = true;
                }
            }
            if(tmp.y-1 >= 0){
                int newk = tmp.obstacle-grid[tmp.x][tmp.y-1];
                if(newk >= 0 && visited[tmp.x][tmp.y-1][newk] == false) {
                    list.add(new Node(tmp.x,tmp.y-1, tmp.step + 1, newk));
                    visited[tmp.x][tmp.y-1][newk] = true;
                }
            }
            if(tmp.y + 1 < grid[0].length){
                int newk = tmp.obstacle-grid[tmp.x][tmp.y+1];
                if(newk >= 0 && visited[tmp.x][tmp.y+1][newk] == false) {
                    list.add(new Node(tmp.x, tmp.y+1, tmp.step + 1, newk));
                    visited[tmp.x][tmp.y+1][newk] = true;
                }
            }
        }
        return count;
    }

}

 

 

 

 

 

發佈了85 篇原創文章 · 獲贊 98 · 訪問量 32萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章