|
| 1 | + |
| 2 | +>仰望星空的人,不应该被嘲笑 |
| 3 | +
|
| 4 | +## 题目描述 |
| 5 | + |
| 6 | +在二维网格 `grid` 上,有 4 种类型的方格: |
| 7 | + |
| 8 | +`1` 表示起始方格。且只有一个起始方格。 |
| 9 | +`2` 表示结束方格,且只有一个结束方格。 |
| 10 | +`0` 表示我们可以走过的空方格。 |
| 11 | +`-1` 表示我们无法跨越的障碍。 |
| 12 | +返回在四个方向(上、下、左、右)上行走时,从起始方格到结束方格的不同路径的数目。 |
| 13 | + |
| 14 | +每一个无障碍方格都要通过一次,但是一条路径中不能重复通过同一个方格。 |
| 15 | + |
| 16 | + |
| 17 | + |
| 18 | +示例 1: |
| 19 | + |
| 20 | +```javascript |
| 21 | +输入:[[1,0,0,0],[0,0,0,0],[0,0,2,-1]] |
| 22 | +输出:2 |
| 23 | +解释:我们有以下两条路径: |
| 24 | +1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2) |
| 25 | +2. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2) |
| 26 | +``` |
| 27 | + |
| 28 | +示例 2: |
| 29 | + |
| 30 | +```javascript |
| 31 | +输入:[[1,0,0,0],[0,0,0,0],[0,0,0,2]] |
| 32 | +输出:4 |
| 33 | +解释:我们有以下四条路径: |
| 34 | +1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2),(2,3) |
| 35 | +2. (0,0),(0,1),(1,1),(1,0),(2,0),(2,1),(2,2),(1,2),(0,2),(0,3),(1,3),(2,3) |
| 36 | +3. (0,0),(1,0),(2,0),(2,1),(2,2),(1,2),(1,1),(0,1),(0,2),(0,3),(1,3),(2,3) |
| 37 | +4. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2),(2,3) |
| 38 | +``` |
| 39 | + |
| 40 | +示例 3: |
| 41 | + |
| 42 | +```javascript |
| 43 | +输入:[[0,1],[2,0]] |
| 44 | +输出:0 |
| 45 | +解释: |
| 46 | +没有一条路能完全穿过每一个空的方格一次。 |
| 47 | +请注意,起始和结束方格可以位于网格中的任意位置。 |
| 48 | +``` |
| 49 | + |
| 50 | + |
| 51 | + |
| 52 | +提示: |
| 53 | + |
| 54 | +```javascript |
| 55 | +1 <= grid.length * grid[0].length <= 20 |
| 56 | +``` |
| 57 | + |
| 58 | +来源:力扣(LeetCode) |
| 59 | +链接:https://leetcode-cn.com/problems/unique-paths-iii |
| 60 | +著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 |
| 61 | + |
| 62 | + |
| 63 | +## 解题思路 |
| 64 | +回溯算法,不过这道题需要我们走完所有空格,所以我们起初遍历的时候需要统计一下空格的数目,然后还有一个注意点就是重点也算是可走的路径的一个点,也需要统计进去,所以代码 `cnt` 值 初始化为 1 |
| 65 | + |
| 66 | +接下来就是回溯过程了,写了一个 `check` 函数,进行简单判断剪枝,然后就是往四个方向搜,每走一个格子就将当前格子设置为障碍(即 `-1`),然后搜索完后,回溯时,需要将障碍重设置为空格。 |
| 67 | + |
| 68 | +```javascript |
| 69 | +/** |
| 70 | + * @param {number[][]} grid |
| 71 | + * @return {number} |
| 72 | + */ |
| 73 | +var uniquePathsIII = function(grid) { |
| 74 | + let cnt = 1 // 统计地图中可走的方格个数,包括终点,故初始值为1 |
| 75 | + let sx,sy // 记录起点坐标 |
| 76 | + for(let i=0;i<grid.length;i++){ |
| 77 | + for(let j=0;j<grid[0].length;j++){ |
| 78 | + if(grid[i][j] === 1){ |
| 79 | + sx = i |
| 80 | + sy = j |
| 81 | + } |
| 82 | + else if(grid[i][j] === 0){ |
| 83 | + cnt++ |
| 84 | + } |
| 85 | + } |
| 86 | + } |
| 87 | + return dfs(sx,sy,cnt,grid) |
| 88 | +}; |
| 89 | +// 剪枝条件 |
| 90 | +let check = (sx,sy,grid) => { |
| 91 | + if(sx<0 || sx>=grid.length || sy<0 || sy>=grid[0].length || grid[sx][sy] == -1) return false |
| 92 | + return true |
| 93 | +} |
| 94 | + |
| 95 | +let dfs = (sx,sy,cnt,grid) => { |
| 96 | + if(!check(sx,sy,grid)) return 0 |
| 97 | + if(grid[sx][sy] === 2){ // 走到终点时,也要判断一下当前所有空格是否走完 |
| 98 | + return cnt === 0 ? 1:0 |
| 99 | + } |
| 100 | + let res = 0 |
| 101 | + grid[sx][sy] = -1 //走过的空格进行标记,设置为障碍即可 |
| 102 | + res += dfs(sx+1,sy,cnt-1,grid) // 四个方向进行搜索 |
| 103 | + res += dfs(sx,sy+1,cnt-1,grid) |
| 104 | + res += dfs(sx-1,sy,cnt-1,grid) |
| 105 | + res += dfs(sx,sy-1,cnt-1,grid) |
| 106 | + grid[sx][sy] = 0 // 回溯过程,不影响后续dfs |
| 107 | + return res |
| 108 | +} |
| 109 | +``` |
| 110 | + |
| 111 | +## 最后 |
| 112 | +文章产出不易,还望各位小伙伴们支持一波! |
| 113 | + |
| 114 | +往期精选: |
| 115 | + |
| 116 | +<a href="https://github.com/Chocolate1999/Front-end-learning-to-organize-notes">小狮子前端の笔记仓库</a> |
| 117 | + |
| 118 | +<a href="https://yangchaoyi.vip/">访问超逸の博客</a>,方便小伙伴阅读玩耍~ |
| 119 | + |
| 120 | + |
| 121 | + |
| 122 | +```javascript |
| 123 | +学如逆水行舟,不进则退 |
| 124 | +``` |
| 125 | + |
| 126 | + |
0 commit comments