程序员面试金典-面试题 08.02. 迷路的机器人

题目:

https://leetcode-cn.com/problems/robot-in-a-grid-lcci/

设想有个机器人坐在一个网格的左上角,网格 r 行 c 列。机器人只能向下或向右移动,但不能走到一些被禁止的网格(有障碍物)。设计一种算法,寻找机器人从左上角移动到右下角的路径。

 

网格中的障碍物和空位置分别用 1 和 0 来表示。

返回一条可行的路径,路径由经过的网格的行号和列号组成。左上角为 0 行 0 列。

示例 1:

输入:
[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]
输出: [[0,0],[0,1],[0,2],[1,2],[2,2]]
解释:
输入中标粗的位置即为输出表示的路径,即
0行0列(左上角) -> 0行1列 -> 0行2列 -> 1行2列 -> 2行2列(右下角)

分析:

这道题超时了好多次,因为只能往下或者往右走,不会出现回路,不过还是要设置已访问数组标记已走过的位置。因为无法到达终点的网格不需要再次浪费时间来遍历了。

程序:

class Solution {
    public List<List<Integer>> pathWithObstacles(int[][] obstacleGrid) {
        m = obstacleGrid.length;
        n = obstacleGrid[0].length;
        visit = new int[m][n];
        List<List<Integer>> res = new ArrayList<>();
        if(dfs(res, obstacleGrid, 0, 0))
            return res;
        res.clear();
        return res;
    }
    private boolean dfs(List<List<Integer>> res, int[][] obstacleGrid, int x, int y){
        if(x >= m || y >= n || visit[x][y] == 1 || obstacleGrid[x][y] == 1)
            return false;
        List<Integer> grid = new ArrayList<>();
        grid.add(x);
        grid.add(y);
        res.add(grid);
        if(x == m-1 && y == n-1)
            return true;
        visit[x][y] = 1;
        for(int i = 0; i < 2; i++){
            int nx = x + move[i][0];
            int ny = y + move[i][1];
            if(dfs(res, obstacleGrid, nx, ny))
                return true;
        }
        res.remove(res.size()-1);
        return false;
    }
    //private List<List<Integer>> res;
    private int m;
    private int n;
    private int[][] visit;
    private int[][] move = new int[][]{{1, 0}, {0, 1}};

}

 

posted @ 2020-03-10 14:02  silentteller  阅读(457)  评论(0编辑  收藏  举报