1391. 检查网格中是否存在有效路径【深度优先搜索DFS】

2020-08-08  本文已影响0人  月下蓑衣江湖夜雨

题目

题目
题目
示例1
示例2-5.png
提示

思路

从格子[0,0]开始,进行dfs,看看是否能到达最后一个节点?
如何标记该节点是否已经访问?grid[][]中取值范围都是1~6,可以将进行过dfs的节点标记为0。
如何标记进行dfs?从[0,0]开始,判断与周边的节点的连通性。如果连通,则对相邻节点进行dfs,这是一个递归的过程。
函数结束后,如果最后一个节点grid[][]的值为0,说明从[0][0]到该节点是连通的。

代码

// 给你一个 m x n 的网格 grid。网格里的每个单元都代表一条街道。grid[i][j] 的街道可以是:

// 1 表示连接左单元格和右单元格的街道。
// 2 表示连接上单元格和下单元格的街道。
// 3 表示连接左单元格和下单元格的街道。
// 4 表示连接右单元格和下单元格的街道。
// 5 表示连接左单元格和上单元格的街道。
// 6 表示连接右单元格和上单元格的街道。

// 解题思路
// 解题思路
// 1、从[0,0]开始dfs
// 2、遍历过的节点的值置为0防止重复遍历;
// 3、满足下面条件之一,则继续dfs
//     当存在向上的接口 && 上方节点存在向下接口;
//     当存在向下的接口 && 下方节点存在向上接口;
//     当存在向左的接口 && 左侧节点存在向右接口;
//     当存在向右的接口 && 右侧节点存在向左接口;
// 4、返回最后一个节点是否遍历过(即是否为0)

// grid = [[1,2,1],[1,2,1]]
// grid中的值的范围是1-6,因此可以复用这个grid,访问grid[0][0]的时候,将其置0(表示已经访问)
// 对上下左右进行dfs
// 如果最后一个节点的值最后为0,说明与[0][0]是连通的!
func hasValidPath(grid [][]int) bool {
    dfs(grid, 0, 0)
    //fmt.Printf("dfs is\n %v\n\n", grid)
    return grid[len(grid)-1][len(grid[0])-1] == 0
}

// 输入1~6,输入方向;
// 输出该方向是否有接口
type Direction uint8
const(
    DirUp Direction = iota
    DirDown
    DirLeft
    DirRight
)

var dirMatrix = [7][4]bool{
    {false, false, false, false},   // 0凑数的
    {false, false, true, true},     // 1 表示连接左单元格和右单元格的街道。
    {true, true, false, false},     // 2 表示连接上单元格和下单元格的街道。
    {false, true, true, false},     // 3 表示连接左单元格和下单元格的街道。
    {false, true, false, true},     // 4 表示连接右单元格和下单元格的街道。
    {true, false, true, false},     // 5 表示连接左单元格和上单元格的街道。
    {true, false, false, true},     // 6 表示连接右单元格和上单元格的街道。
}

// 数字num在方向dir上是否有入口
func hasEntrance(num int, dir Direction) bool {
    if num < 1 || num > 6 {
        return false
    }

    return dirMatrix[num][dir]
}

// grid既作为输入参数,也作为是否访问的标记
// row行,col列,表示当前对那个节点进行dfs
func dfs(grid [][]int, row, col int) {
    // 递归停止条件
    if grid[row][col] == 0 {
        return
    }

    num := grid[row][col]
    grid[row][col] = 0 // 标记该点已经被访问了

    // 如果不是第1行
    if row > 0 && hasEntrance(num, DirUp) && hasEntrance(grid[row-1][col], DirDown) {
        dfs(grid, row-1, col)
    }

    // 如果不是最后1行
    if row < len(grid)-1 && hasEntrance(num, DirDown) && hasEntrance(grid[row+1][col], DirUp) {
        dfs(grid, row+1, col)
    }

    // 如果不是第1列
    if col > 0 && hasEntrance(num, DirLeft) && hasEntrance(grid[row][col-1], DirRight) {
        dfs(grid, row, col-1)
    }

    // 如果不是最后1列(len(grid[0])注意边界条件)
    if col < len(grid[0]) -1 && hasEntrance(num, DirRight) && hasEntrance(grid[row][col+1], DirLeft) {
        dfs(grid, row, col+1)
    }
}
上一篇下一篇

猜你喜欢

热点阅读