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

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

相关推荐
小沈熬夜秃头中୧⍤⃝10 分钟前
【贪心算法】No.1---贪心算法(1)
算法·贪心算法
CSXB9911 分钟前
三十四、Python基础语法(文件操作-上)
开发语言·python·功能测试·测试工具
木向42 分钟前
leetcode92:反转链表||
数据结构·c++·算法·leetcode·链表
阿阿越44 分钟前
算法每日练 -- 双指针篇(持续更新中)
数据结构·c++·算法
亚图跨际1 小时前
MATLAB和Python及R潜变量模型和降维
python·matlab·r语言·生物学·潜变量模型
skaiuijing1 小时前
Sparrow系列拓展篇:对调度层进行抽象并引入IPC机制信号量
c语言·算法·操作系统·调度算法·操作系统内核
IT古董1 小时前
【机器学习】决定系数(R²:Coefficient of Determination)
人工智能·python·机器学习
德育处主任Pro1 小时前
『Django』APIView基于类的用法
后端·python·django
Star Patrick1 小时前
算法训练(leetcode)二刷第十九天 | *39. 组合总和、*40. 组合总和 II、*131. 分割回文串
python·算法·leetcode
武子康2 小时前
大数据-213 数据挖掘 机器学习理论 - KMeans Python 实现 距离计算函数 质心函数 聚类函数
大数据·人工智能·python·机器学习·数据挖掘·scikit-learn·kmeans