leetcode-javascript
leetcode-javascript copied to clipboard
不同路径 III-980
在二维网格 grid 上,有 4 种类型的方格:
1 表示起始方格。且只有一个起始方格。 2 表示结束方格,且只有一个结束方格。 0 表示我们可以走过的空方格。 -1 表示我们无法跨越的障碍。 返回在四个方向(上、下、左、右)上行走时,从起始方格到结束方格的不同路径的数目,每一个无障碍方格都要通过一次。
示例 1:
输入:[[1,0,0,0],[0,0,0,0],[0,0,2,-1]]
输出:2
解释:我们有以下两条路径:
1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2)
2. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2)
示例 2:
输入:[[1,0,0,0],[0,0,0,0],[0,0,0,2]]
输出:4
解释:我们有以下四条路径:
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)
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)
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)
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)
示例 3:
输入:[[0,1],[2,0]]
输出:0
解释:
没有一条路能完全穿过每一个空的方格一次。
请注意,起始和结束方格可以位于网格中的任意位置。
提示:
1 <= grid.length * grid[0].length <= 20
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/unique-paths-iii 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
先遍历一遍所有的格子,统计 0
出现的次数和 1
起点出现的位置。
然后就是和其他题目一样的递归回溯流程,从起点开始不断的向着上下左右四个方向扩散,并且每次递归遇到 0
的格子都把当前记录的数量加1,并且传入下一次递归中。当到达了2
的时候,查看走过的 0
数量是否等于最开始统计的次数。如果相等,则记录为一次有效路径。
/**
* @param {number[][]} grid
* @return {number}
*/
let uniquePathsIII = function (grid) {
let maxY = grid.length
if (!maxY) return 0
let maxX = grid[0].length
let validCellsCount = 0
let entry
let visited = []
for (let y = 0; y < maxY; y++) {
visited[y] = []
for (let x = 0; x < maxX; x++) {
let val = grid[y][x]
if (val === 0) {
validCellsCount++
}
if (val === 1) {
entry = [y, x]
}
}
}
let isValid = (y, x) => {
return y >= 0 && y < maxY && x >= 0 && x < maxX && !visited[y][x] && grid[y][x] !== -1
}
let dirs = [[-1, 0], [1, 0], [0, -1], [0, 1]]
let res = 0
let dfs = (y, x, passCount) => {
let val = grid[y][x]
if (val === 2) {
if (passCount === validCellsCount) {
res++
}
return
}else if (val === 0) {
passCount += 1
}
for (let [diffY, diffX] of dirs) {
let nextY = y + diffY
let nextX = x + diffX
if (isValid(nextY, nextX)) {
visited[nextY][nextX] = true
dfs(nextY, nextX, passCount)
visited[nextY][nextX] = false
}
}
}
let [entryY, entryX] = entry
visited[entryY][entryX] = true
dfs(entryY, entryX, 0)
return res
};
你好,请问下在递归执行完dfs函数时,为什么还需要执行visited[nextY][nextX] = false
,将走过的路径设置为false。