leetcode-javascript icon indicating copy to clipboard operation
leetcode-javascript copied to clipboard

不同路径 III-980

Open sl1673495 opened this issue 4 years ago • 1 comments

在二维网格 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
};

sl1673495 avatar Jun 29 '20 02:06 sl1673495

你好,请问下在递归执行完dfs函数时,为什么还需要执行visited[nextY][nextX] = false,将走过的路径设置为false。

BeliefRC avatar Aug 02 '20 04:08 BeliefRC