DFS秒杀【leetcode-岛屿类问题】!!!

473 阅读2分钟

起因

故事是这样的,就在前几天力扣出了每日一题小火花image.png! 结果我的小火花还没燃烧起来就被太平洋和大西洋的水浇灭了!(417. 太平洋大西洋水流问题)

image.png

然后我一气之下,恶补了一下题解中的DFS\color{red}{DFS}深度优先搜索。通过自行理解修炼,今日狂斩岛屿问题!

image.png

不多bb直接献上模板!!!

模板

二维数组grid代表地图,值为1的一般代表岛,值为0的一般代表水。 一般问题求:岛屿数量,孤岛数量,岛屿面积等等,都是类似的,用下面模板再根据条件修改一点点即可。

下面解题模板,以求岛屿数量为例:

var func = (grid) => {
    // m行,n列,dire方向
    const [m, n, dire] = [grid.length, grid[0].length, [[-1, 0], [1, 0], [0, 1], [0, -1]]]

    let count=0 //用于记录岛屿数量

    // 构建DFS函数,(x,y)为坐标
    const dfs = (x, y, grid) => {
        // 判断是水是岛,模板以判断是否为岛屿为例
        if (!grid[x][y])
            return
        // 如果是岛,到过这个岛,则设为水。
        grid[x][y] = 0

        // 遍历方向,也就是最重要的移动部分!
        for (let dir of dire) {
            // 获取新坐标
            const [newX, newY] = [x + dir[0], y + dir[1]]
            // 如果新坐标满足题目条件,比如:也是一座岛屿
            if (newX >= 0 && newX < m && newY >= 0 && newY < n && grid[newX][newY] == 1)
                dfs(newX, newY, grid) //继续移动,直到不满足条件
        }
    }

    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            // 从起点出发,探索岛屿,并记录数量
            if (grid[i][j]) {
                // 每开始一次dfs就可以确定一座岛屿
                dfs(i, j, grid)
                count++
            }
        }
    }
    return count
}

战绩

其实看到这就可以了,前面的理解了就够了。兄弟们让一让,后面我要开始装X了

200. 岛屿数量

image.png

个人题解:

var numIslands = function (grid) {
    const [m, n, dire] = [grid.length, grid[0].length, [[-1, 0], [1, 0], [0, 1], [0, -1]]]
    let count = 0
    const dfs = (x, y, grid) => {
        if (grid[x][y] === "0")
            return
        grid[x][y] = "0"
        for (let dir of dire) {
            const [newX, newY] = [x + dir[0], y + dir[1]]
            if (newX >= 0 && newX < m && newY >= 0 && newY < n && grid[newX][newY] == "1")
                dfs(newX, newY, grid)
        }
    }
    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            if (grid[i][j] === "1") {
                dfs(i, j, grid)
                count++
            }
        }
    }
    return count
};

695. 岛屿的最大面积

image.png 个人题解:

var maxAreaOfIsland = function (grid) {
    const m = grid.length, n = grid[0].length, dire = [[-1, 0], [1, 0], [0, -1], [0, 1]]
    let maxS = 0,count=0
    let dfs = (x, y, grid) => {
        if (!grid[x][y])
            return
        grid[x][y] = 0
        count++
        for (let dir of dire) {
            const [newX, newY] = [dir[0] + x, dir[1] + y]
            if (newX >= 0 && newX < m && newY >= 0 && newY < n && grid[newX][newY] == 1) {
                dfs(newX, newY, grid)
            }
        }
    }
    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            if (grid[i][j]){
                dfs(i, j, grid,0)
                maxS=Math.max(maxS,count)
                count=0
            }
        }
    }
    return maxS
};

1254. 统计封闭岛屿的数目

image.png 个人题解:

var closedIsland = function (grid) {
    const m = grid.length, n = grid[0].length, dire = [[-1, 0], [1, 0], [0, -1], [0, 1]]
    let count = 0,flag=0
    let dfs = (x, y, grid) => {
        if (grid[x][y])
            return
        if(x==0||y==0||x==m-1||y==n-1) flag=1
        grid[x][y] = 1
        for (let dir of dire) {
            const [newX, newY] = [dir[0] + x, dir[1] + y]
            if (newX >= 0 && newX < m && newY >= 0 && newY < n && grid[newX][newY] == 0) {
                dfs(newX, newY, grid)
            }
        }
    }
    for (let i = 1; i < m-1; i++) {
        for (let j = 1; j < n-1; j++) {
            if (!grid[i][j]) {
                dfs(i, j, grid)
                if(flag){
                    flag=0
                }else count++
            }
        }
    }
    return count
};

329. 矩阵中的最长递增路径

XW~~X}YF%HZE)]%YP%0_Q.png 个人题解:

var longestIncreasingPath = function (matrix) {
    const m = matrix.length, n = matrix[0].length, dire = [[-1, 0], [1, 0], [0, -1], [0, 1]]
    let maxLen = 0, mmp = new Array(m).fill(0).map(v => new Array(n).fill(0))
    let dfs = (x, y, grid) => {
        if (!mmp[x][y]) mmp[x][y]++
        for (let dir of dire) {
            const [X, Y] = [x + dir[0], y + dir[1]]
            if (X >= 0 && X < m && Y >= 0 && Y < n && grid[X][Y] > grid[x][y]) {
                if (!mmp[X][Y])
                    dfs(X, Y, grid, mmp[X][Y])
                mmp[x][y] = Math.max(mmp[X][Y] + 1, mmp[x][y])
            }
        }
    }
    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            dfs(i, j, matrix)
            maxLen = Math.max(maxLen, mmp[i][j])
        }
    }
    return maxLen
};

好的,又可以愉快地每日一题养火苗了~~~

image.png

后续

可恶啊!今天的每日一题:427. 建立四叉树又是个啥啊?还能不能好好玩耍???