DFS岛屿问题部分汇总

LeetCode 上的岛屿问题通常是关于矩阵中岛屿的数量、面积、周长等问题。这些问题可以归纳为图的遍历问题,常见的解决方法包括深度优先搜索(DFS)和广度优先搜索(BFS)。 今天汇总一下我做过的一些DFS解决的岛屿问题。

463. 岛屿的周长 - 力扣(LeetCode)

给定一个 row x col 的二维网格地图 grid ,其中:grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域。

网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。

岛屿中没有"湖"("湖" 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。

示例 1:

css 复制代码
输入: grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]]
输出: 16
解释: 它的周长是上面图片中的 16 个黄色的边

示例 2:

lua 复制代码
输入: grid = [[1]]
输出: 4

示例 3:

lua 复制代码
输入: grid = [[1,0]]
输出: 4

提示:

  • row == grid.length
  • col == grid[i].length
  • 1 <= row, col <= 100
  • grid[i][j]01

代码

py 复制代码
class Solution:
    def islandPerimeter(self, grid):
        def dfs(grid, i, j):
            if not 0 <= i < len(grid) or not 0 <= j < len(grid[0]) or grid[i][j] == 0:
                return 1
            if grid[i][j] == -1:
                return 0
            grid[i][j] = -1
            t = dfs(grid, i - 1, j)
            b = dfs(grid, i + 1, j)
            l = dfs(grid, i, j - 1)
            r = dfs(grid, i, j + 1)
            return t + b + l + r

        count = 0
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == 1:
                    count += dfs(grid, i, j)

        return count

这个问题的解法是使用深度优先搜索(DFS)。

  1. dfs 函数是递归地计算从当前位置 (i, j) 出发的岛屿的周长。

    • 如果当前位置越界或者是水域(grid[i][j] == 0),返回 1(表示边界)。
    • 如果当前位置已经被访问过(grid[i][j] == -1),返回 0。
    • 将当前位置标记为已访问(grid[i][j] = -1)。
    • 递归地计算当前位置的上、下、左、右四个方向的周长,并将结果相加。
  2. 主函数 islandPerimeter 遍历整个网格,当发现岛屿(grid[i][j] == 1)时,调用 dfs 函数计算该岛屿的周长,并累加到 count 变量中。

  3. 最终返回累加的周长 count

这样,通过深度优先搜索递归计算每个岛屿的周长,最终得到整个岛屿的总周长。这题的关键点是在计算周长时,遇到岛屿的边界要返回1,同时需要标记已经访问过的岛屿,避免重复计算。

695. 岛屿的最大面积 - 力扣(LeetCode)

给你一个大小为 m x n 的二进制矩阵 grid

岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。

岛屿的面积是岛上值为 1 的单元格的数目。

计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0

示例 1:

css 复制代码
输入: grid = [[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],[0,1,0,0,1,1,0,0,1,0,1,0,0],[0,1,0,0,1,1,0,0,1,1,1,0,0],[0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,0,0,0,0,0,0,1,1,0,0,0,0]]
输出: 6
解释: 答案不应该是 11 ,因为岛屿只能包含水平或垂直这四个方向上的 1 。

示例 2:

lua 复制代码
输入: grid = [[0,0,0,0,0,0,0,0]]
输出: 0

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 50
  • grid[i][j]01

代码

py 复制代码
class Solution:
    def maxAreaOfIsland(self, grid):
        m, n = len(grid), len(grid[0])

        def dfs(grid, i, j):
            if not 0 <= i < m or not 0 <= j < n or grid[i][j] == 0:
                return 0
            grid[i][j] = 0
            t = dfs(grid, i - 1, j)
            b = dfs(grid, i + 1, j)
            l = dfs(grid, i, j - 1)
            r = dfs(grid, i, j + 1)
            return t + b + l + r + 1

        maxS = 0
        for i in range(m):
            for j in range(n):
                if grid[i][j] == 1:
                    s = dfs(grid, i, j)
                    maxS = max(maxS,s)
        return maxS

这个解法同样是使用深度优先搜索(DFS)。以下是对代码的解析:

  1. dfs 函数负责计算从当前位置 (i, j) 出发的岛屿的面积。

    • 如果当前位置越界或者是水域(grid[i][j] == 0),返回 0。
    • 将当前位置标记为已访问(grid[i][j] = 0)。
    • 递归地计算当前位置的上、下、左、右四个方向的面积,并将结果相加。
    • 最终返回当前位置的面积 + 1,表示当前位置是陆地。
  2. 主函数 maxAreaOfIsland 遍历整个网格,当发现岛屿(grid[i][j] == 1)时,调用 dfs 函数计算该岛屿的面积,并与当前最大面积 maxS 比较,更新 maxS

  3. 最终返回最大面积 maxS

这个解法的核心思想是通过深度优先搜索递归地计算每个岛屿的面积,并在遍历过程中不断更新最大面积。同样地,已经访问过的陆地需要标记为水域,以避免重复计算。

200. 岛屿数量 - 力扣(LeetCode)

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

示例 1:

css 复制代码
输入: grid = [  ["1","1","1","1","0"],
  ["1","1","0","1","0"],
  ["1","1","0","0","0"],
  ["0","0","0","0","0"]
]
输出: 1

示例 2:

css 复制代码
输入: grid = [  ["1","1","0","0","0"],
  ["1","1","0","0","0"],
  ["0","0","1","0","0"],
  ["0","0","0","1","1"]
]
输出: 3

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 300
  • grid[i][j] 的值为 '0''1'

代码

py 复制代码
class Solution:
    def numIslands(self, grid) -> int:
        m, n = len(grid), len(grid[0])

        def dfs(grid,i, j):
            if not 0 <= i < m or not 0 <= j < n or grid[i][j] == '0':
                return
            grid[i][j] = '0'
            dfs(grid, i - 1, j)
            dfs(grid, i + 1, j)
            dfs(grid, i, j - 1)
            dfs(grid, i, j + 1)
        cnt = 0
        for i in range(m):
            for j in range(n):
                if grid[i][j] == '1':
                    dfs(grid,i,j)
                    cnt += 1
        return cnt

这个解法同样使用了深度优先搜索(DFS)。

  1. dfs 函数负责将当前位置 (i, j) 所在的岛屿标记为已访问,递归地将相邻的陆地标记为已访问。

    • 如果当前位置越界或者是水域(grid[i][j] == '0'),直接返回。
    • 将当前位置标记为已访问(grid[i][j] = '0')。
    • 递归地访问当前位置的上、下、左、右四个方向。
  2. 主函数 numIslands 遍历整个网格,当发现岛屿(grid[i][j] == '1')时,调用 dfs 函数将整个岛屿标记为已访问,并增加岛屿数量计数器 cnt

  3. 最终返回岛屿数量 cnt

这个解法的思路是遍历整个网格,每当发现未访问的岛屿时,通过深度优先搜索将整个岛屿标记为已访问。遍历完整个网格后,所有岛屿都被访问过,最终返回岛屿数量。

相关推荐
补三补四2 分钟前
Django与视图
数据库·python·django·sqlite
2301_807449209 分钟前
字符串相乘——力扣
java·算法·leetcode
木卯11 分钟前
5种创建型设计模式笔记(Python实现)
python·设计模式
张琪杭28 分钟前
pytorch tensor创建tensor
人工智能·pytorch·python
星星点点洲38 分钟前
【RAG】RAG 系统的基本搭建流程(ES关键词检索示例)
python·elasticsearch
yadanuof1 小时前
leetcode hot100 图论
leetcode·深度优先·图论
带娃的IT创业者1 小时前
《Python实战进阶》No18: 使用 Apache Spark 进行分布式计算
python·spark·apache
Tomorrow'sThinker1 小时前
Python零基础学习第三天:函数与数据结构
开发语言·windows·python
---yx8989781 小时前
数字人系统源码---v10技术五大底层架构链路全局开发思路
算法·架构·数字人·数字人源码·数字人系统
元媛媛1 小时前
Python - 轻量级后端框架 Flask
开发语言·python·flask