【python】岛屿数量

本文介绍了如何使用Python解决一个问题,即给定一个由1(陆地)和0(水)组成的二维网格,计算其中岛屿的数量。文章详细讲解了分析方法、注意事项,包括遍历策略、坐标范围检查和计数规则,并给出了Solution类的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

python系列文章目录

【python】基于cv2提取图片上的文本内容
【python】简单作图
【python】数组字符串等实用
【python】sort与sorted排序使用
【python】对角线遍历



说明

给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。此外,你可以假设该网格的四条边均被水包围。示例 1:
输入:grid = [
[“1”,“1”,“0”,“0”,“0”],
[“1”,“1”,“0”,“0”,“0”],
[“0”,“0”,“1”,“0”,“0”],
[“0”,“0”,“0”,“1”,“1”]
]
输出:3


1.分析

对于示例1, 4 x 5 的矩阵,岛屿分布如下矩阵所示,岛屿数量是"1" 连接在一起的块数,即为3。
[ " 1 " " 1 " " 1 " " 1 " " 1 " " 1 " " 1 " ] \left[\begin{array}{c|c|c|c|c} "1" & "1" & & & \\ \hline "1" & "1"& \\ \hline & & "1"\\ \hline & & & "1" & "1" \\ \end{array}\right] "1""1""1""1""1""1""1"
对于矩阵的任意一个坐标[row][col],如何去找到与其连接的"1" 呢?需要考虑该坐标的上下左右四个坐标,而且需要满足不能坐标溢出,即:

  • r o w − 1 ≥ 0 row -1\geq0 row10
  • c o l − 1 ≥ 0 col -1\geq0 col10
  • r o w + 1 < 行数 row + 1<行数 row+1<行数
  • c o l + 1 < 列数 col + 1<列数 col+1<列数

[ r o w − 1 , c o l r o w , c o l − 1 r o w , c o l r o w , c o l + 1 r o w + 1 , c o l ] \left[\begin{array}{c|c|c} & row -1, col & \\ \hline row, col -1&row, col&row, col +1 \\ \hline & row +1, col & \\ \end{array}\right] row,col1row1,colrow,colrow+1,colrow,col+1

2.注意事项

2.1 遍历

遍历过的坐标可以作为标记已经遍历,如下代码证定义一个与矩阵同样大小的零矩阵,如果已经遍历过,则labels[row][col] = 1

2.2 区间

行列坐标不能溢出

2.3 计数

如果遍历到某个坐标的值为“1”,则满足岛屿的条件,count += 1。可以去搜索去四周的坐标是否为“1”,如果四周的坐标为“1”,则需要标记,避免重复count。

3.代码实现

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        rows = len(grid)
        cols = len(grid[0])
        labels = [[0 for i in range(cols)] for j in range(rows)]
        def search(row, col):
            labels[row][col] = 1
            #up
            if row - 1 >= 0 and labels[row-1][col] == 0 and grid[row-1][col] == '1':
                labels[row-1][col] = 1
                search(row-1, col)
            #down
            if row + 1 < rows and labels[row+1][col] == 0 and grid[row+1][col] == '1':
                labels[row+1][col] == 1
                search(row+1, col)
            #left
            if col - 1 >= 0 and labels[row][col-1]== 0 and grid[row][col-1] == '1':
                labels[row][col-1]=1
                search(row, col - 1)
            #right
            if col + 1 < cols and labels[row][col+1]==0 and grid[row][col+1] == '1':
                labels[row][col+1]=1
                search(row, col+1)
            
        count = 0
        for row in range(rows):
            for col in range(cols):
                
                if grid[row][col] == '1' and labels[row][col] == 0:
                    count += 1
                    search(row, col)
        return count   
<think>好的,我现在需要帮助用户了解如何用Python实现计算岛屿数量的算法。首先,我得回忆一下这个问题。题目是说,给定一个二维网格,其中'1'代表陆地,'0'代表水域,相邻的陆地(上下左右)组成一个岛屿,要求统计岛屿数量。用户提供的引用资料里提到了一些方法,比如递归、迭代、双向队列、并查集等。我需要把这些方法中的主要思路整理出来,并给出代码示例。 首先,我得确定基本思路。通常,这类问题可以通过深度优先搜索(DFS)或广度优先搜索(BFS)来解决。用户提到的引用中也提到了递归(DFS)和迭代(BFS)的方法。并查集可能稍微复杂一些,但也是一个有效的方法。不过对于初学者来说,DFS和BFS可能更容易理解。 我应该从最简单的递归方法开始。递归DFS的思路是遍历整个网格,当遇到一个'1'时,就启动DFS,将所有相邻的'1'都标记为已访问,通常是通过修改为'0'来避免重复计算。这样,每次遇到一个新的'1',岛屿数量就加一,然后递归处理周围四个方向。 然后,可能需要考虑迭代的方法,比如用队列实现的BFS。这里同样需要遍历网格,遇到'1'时,启动BFS,将周围的'1'加入队列,并逐个处理,直到队列为空。这样也能标记整个岛屿。 另外,用户提供的引用里提到了高速双向队列,可能是指使用collections.deque来提高效率,这一点可以在BFS部分提到。并查集的方法可能稍微复杂,需要处理每个节点的父节点,合并相邻的陆地,最后统计根节点的数量。不过对于一般情况,DFS和BFS已经足够。 接下来,我需要确保代码示例的正确性。比如递归的DFS函数需要处理边界条件,比如索引是否超出范围,当前节点是否为'1'。同时,要修改访问过的节点,防止重复计算。BFS的示例同样需要注意这些,同时使用队列来存储待处理的节点。 另外,用户可能关心时间复杂度和空间复杂度。这个问题的时间复杂度通常是O(M*N),因为每个节点最多被访问一次。空间复杂度对于DFS来说,最坏情况下是O(M*N)(比如整个网格都是陆地,递归栈的深度),而BFS的空间复杂度取决于队列的大小,可能也是O(min(M,N)),但具体可能需要更详细的分析。 在编写步骤的时候,应该分点说明,比如遍历网格、发现陆地、标记已访问、统计数量等。代码部分需要符合Python语法,使用正确的缩进和结构。同时,需要解释每个步骤的作用,比如双层循环的作用,递归或迭代的处理方式。 可能还需要比较不同方法的优缺点。比如递归的DFS代码简洁,但可能有栈溢出的风险;而BFS使用队列,适合较大的网格。并查集可能在处理动态连接问题时更高效,但实现起来稍微复杂。 最后,生成的相关问题需要考虑用户可能进一步想知道的内容,比如如何优化算法,处理大规模数据,或者不同方法的性能比较等。 总结一下,我需要整理出DFS和BFS两种方法的实现步骤,给出代码示例,并简要分析复杂度。同时,比较不同方法的适用场景,确保用户能够理解并选择合适的方法。</think>### 逐步解释:Python实现计算岛屿数量 #### 1. **问题理解** 岛屿数量问题要求在二维网格中统计由相邻陆地('1')组成的独立区域数量,相邻指水平或垂直方向相连[^3][^4]。 #### 2. **核心思路** 通过遍历网格中的每个点: - 遇到陆地('1')时启动**深度优先搜索(DFS)**或**广度优先搜索(BFS)**,将所有相连的陆地标记为已访问。 - 每启动一次搜索,岛屿数量+1。 #### 3. **DFS递归实现** ```python def num_islands_dfs(grid): if not grid: return 0 rows, cols = len(grid), len(grid[0]) count = 0 def dfs(i, j): if i < 0 or j < 0 or i >= rows or j >= cols or grid[i][j] == '0': return grid[i][j] = '0' # 标记为已访问 # 递归搜索四个方向 dfs(i + 1, j) dfs(i - 1, j) dfs(i, j + 1) dfs(i, j - 1) for i in range(rows): for j in range(cols): if grid[i][j] == '1': dfs(i, j) count += 1 return count ``` **步骤说明**: 1. 遍历每个网格点。 2. 遇到未访问的陆地时,递归标记所有相连陆地为'0'。 3. 统计启动搜索的次数即为岛屿数量[^5]。 #### 4. **BFS迭代实现** ```python from collections import deque def num_islands_bfs(grid): if not grid: return 0 rows, cols = len(grid), len(grid[0]) count = 0 for i in range(rows): for j in range(cols): if grid[i][j] == '1': queue = deque([(i, j)]) grid[i][j] = '0' # 标记起点 while queue: x, y = queue.popleft() for dx, dy in [(-1,0), (1,0), (0,-1), (0,1)]: nx, ny = x + dx, y + dy if 0 <= nx < rows and 0 <= ny < cols and grid[nx][ny] == '1': grid[nx][ny] = '0' queue.append((nx, ny)) count += 1 return count ``` **特点**: - 使用队列实现层级遍历。 - 避免递归栈溢出风险,适合大规模网格[^2]。 #### 5. **复杂度分析** - **时间复杂度**:$$O(M \times N)$$(每个节点仅访问一次)。 - **空间复杂度**: - DFS:$$O(M \times N)$$(递归栈深度)。 - BFS:$$O(\min(M, N))$$(队列最大长度)[^5]。 --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值