🚩传送门:力扣题目
题目
在二维网格 上,有
种类型的方格:
表示起始方格。且只有一个起始方格。
表示结束方格,且只有一个结束方格。
表示我们可以走过的空方格。
表示我们无法跨越的障碍。
返回在四个方向( 上、下、左、右 )上行走时,从起始方格到结束方格的不同路径的数目。
每一个无障碍方格都要通过一次,但是一条路径中不能重复通过同一个方格。
示例 1:
输入:[[1,0,0,0],[0,0,0,0],[0,0,2,-1]] 输出:2 解释:我们有以下两条路径:
- (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2)
- (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2)
解题思路:深搜
让我们尝试遍历每一个 方格,并在走过的方格里留下一个障碍。回溯的时候,我们要删除那些自己留下的障碍。
深搜所有的可能路径,对到达终点的路径判断是否已经全部路过了每一个 方格(即数组中不存在
方格),满足条件的全局变量
加
。
复杂度分析
时间复杂度:,其中
是这个二维网格行与列的大小。
空间复杂度:
官方代码
class Solution {int res;public int uniquePathsIII(int[][] grid) {if (grid == null || grid.length == 0) return 0;res = 0;// 找起点位置开始dfsfor (int i = 0; i < grid.length; i++) {for (int j = 0; j < grid[i].length; j++) {if (grid[i][j] == 1) {dfs(grid, i, j);return res;}}}return res;}private void dfs(int[][] grid, int i, int j) {// 边界合法性检查if (i < 0 || i >= grid.length || j < 0 || j >= grid[i].length) return;// 判断能否跨越if (grid[i][j] == -1) return;// 遇到终点,判断当前路径是否满足要求if (grid[i][j] == 2) {// 检查是否还有未走的空格for (int k = 0; k < grid.length; k++) {for (int l = 0; l < grid[k].length; l++) {if (grid[k][l] == 0) return;}}res++;return;}// 对可行点(i,j)标记访问grid[i][j] = -1;// 定义四向搜索int[][] dir = new int[][]{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};for (int k = 0; k < dir.length; k++) {dfs(grid,i+dir[k][0],j+dir[k][1]);}// 四向搜索完成,取消标记grid[i][j] = 0;}}
