力扣:08.02. 迷路的机器人

167 阅读2分钟

「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战

描述

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

img

网格中的障碍物和空位置分别用 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列(右下角)
​
  • 提示:
  • rc 的值均不超过 100。

解析

深度优先遍历方法,同时使用blockGrid数组记录包含i、j的路径是否能继续向下寻找,当包含i、j的路径不能找到合适的完整径路时,直接放弃搜索。

  1. 当obstacleGridi == 0 && i == xLen - 1 && j == yLen - 1时,找到路径递归结束,返回true,否则返回false;
  2. 当i + 1 < xLen && blockGridi + 1 != 1时,向下走nextStep(i + 1, j);
  3. 当向下走寻路失败且j + 1 < yLen && blockGridi != 1时,向右走nextStep(i, j + 1);
  4. 当向下走和向右走都失败时,令blockGridi = 1,即包含i、j的路径不能找到合适的完整径路,并返回false;
class Solution {
    int xLen, yLen;
    int xTop = -1, yTop = -1;
    int[] xStack, yStack;
    int[][] obstacleGrid;
    int[][] blockGrid;
​
    public List<List<Integer>> pathWithObstacles(int[][] obstacleGrid) {
        if (obstacleGrid == null || obstacleGrid.length == 0) {
            return new ArrayList<List<Integer>>();
        }
​
        this.obstacleGrid = obstacleGrid;
        int len = obstacleGrid.length + obstacleGrid[0].length - 1;
        xLen = obstacleGrid.length;
        yLen = obstacleGrid[0].length;
        this.blockGrid = new int[xLen][yLen];
        xStack = new int[len];
        yStack = new int[len];
​
        boolean b = nextStep(0, 0);
​
        List<List<Integer>> lists = new ArrayList<List<Integer>>();
        for (int i = 0; i < len && b; i++) {
            List<Integer> list = new ArrayList<Integer>();
            list.add(xStack[i]);
            list.add(yStack[i]);
            lists.add(list);
        }
​
        return lists;
    }
​
    public boolean nextStep(int i, int j) {
        boolean b = false;
        if (this.obstacleGrid[i][j] == 0) {
            if (this.blockGrid[i][j] != 1) {
                this.blockGrid[i][j] = 0;
            }
​
            xStack[++xTop] = i;
            yStack[++yTop] = j;
            if (i == xLen - 1 && j == yLen - 1) {
                return true;
            }
​
            if (i + 1 < xLen && this.blockGrid[i + 1][j] != 1) {
                b = nextStep(i + 1, j);
            }
            if (!b && j + 1 < yLen && this.blockGrid[i][j + 1] != 1) {
                b = nextStep(i, j + 1);
            }
            if (!b) {
                this.blockGrid[i][j] = 1;
                xTop--;
                yTop--;
            }
        }
​
        return b;
    }
}
​

运行结果:

执行结果:通过

执行用时:1 ms, 在所有 Java 提交中击败了98.85%的用户

内存消耗:39.6 MB, 在所有 Java 提交中击败了19.80%的用户