首页 > 其他分享 >LeetCode【0200】岛屿数量

LeetCode【0200】岛屿数量

时间:2024-11-24 20:31:45浏览次数:10  
标签:陆地 标记 岛屿 网格 DFS grid 0200 LeetCode

本文目录

1 中文题目

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

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

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

示例:

 输入:grid = [
  ["1","1","1","1","0"],
  ["1","1","0","1","0"],
  ["1","1","0","0","0"],
  ["0","0","0","0","0"]
]
输出:1
输入: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 1 \leq m, n \leq 300 1≤m,n≤300
  • grid[i][j] 的值为 ‘0’ 或 ‘1

2 Python求解

2.1 求解思路

通过遍历整个网格,每当发现一个未访问的陆地(‘1’)时,使用深度优先搜索将与其相连的所有陆地都标记为已访问(修改为’0’),同时计数器加1,这样每次DFS标记的就是一个完整的岛屿,最终计数器的值就是岛屿的数量。

2.2 涉及方法

  • 深度优先搜索(Depth-First Search, DFS)
  • 洪水填充算法(Flood Fill Algorithm)

2.3 求解示例

输入矩阵
grid = [
  ["1","1","0","0","0"],
  ["1","1","0","0","0"],
  ["0","0","1","0","0"],
  ["0","0","0","1","1"]
]
第一次发现陆地:grid[0][0] = '1'
count = 1
执行DFS,标记第一个岛屿(标记为'0'):
[["0","0","0","0","0"],
 ["0","0","0","0","0"],
 ["0","0","1","0","0"],
 ["0","0","0","1","1"]]

第二次发现陆地:grid[2][2] = '1'
count = 2
执行DFS,标记第二个岛屿:
[["0","0","0","0","0"],
 ["0","0","0","0","0"],
 ["0","0","0","0","0"],
 ["0","0","0","1","1"]]

第三次发现陆地:grid[3][3] = '1'
count = 3
执行DFS,标记第三个岛屿:
[["0","0","0","0","0"],
 ["0","0","0","0","0"],
 ["0","0","0","0","0"],
 ["0","0","0","0","0"]]

最终返回:3

2.4 Python代码

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        # 获取网格的行数和列数
        rows = len(grid)
        if not rows:
            return 0
        cols = len(grid[0])
        
        # 岛屿计数器
        count = 0
        
        # 深度优先搜索函数,用于标记相连的陆地
        def dfs(i: int, j: int) -> None:
            # 边界检查和水域检查
            if (i < 0 or i >= rows or 
                j < 0 or j >= cols or 
                grid[i][j] != '1'):
                return
            
            # 将当前陆地标记为已访问(修改为'0')
            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':
                    count += 1  # 发现新岛屿
                    dfs(i, j)   # 标记整个岛屿
        
        return count

2.5 复杂度分析

  • 时间复杂度:O(m×n),m和n分别是网格的行数和列数
    • 每个格子最多被访问一次
    • DFS的递归调用不会重复访问已标记的格子
    • 总体需要遍历整个网格一次
  • 空间复杂度:O(m×n)
    • 最坏情况下(整个网格都是陆地且呈蛇形)
    • DFS的递归调用栈深度可能达到m×n
    • 在实际情况下,递归深度通常远小于m×n

3 题目总结

题目难度:中等
数据结构:矩阵
应用算法:深度优先搜索(Depth-First Search, DFS)

标签:陆地,标记,岛屿,网格,DFS,grid,0200,LeetCode
From: https://blog.csdn.net/qq_32882309/article/details/143987050

相关文章

  • Leetcode刷题5--- 最长回文子串 Python
    Leetcode刷题5—最长回文子串Python问题描述给你一个字符串s,找到s中最长的回文子串。示例示例1:“”"输入:s=“babad”输出:“bab”解释:“aba”同样是符合题意的答案。“”"示例2:“”"输入:s=“cbbd”输出:“bb”“”"提示......
  • 【贪心算法-第三弹——Leetcode-179.最大数】
    1.题目解析题目来源测试用例 2.算法原理 3.实战代码代码解析 *4.贪心策略的合理性证明(离散数学——全序关系)完全性反对称性传递性 1.题目解析题目来源179.最大数——力扣测试用例 2.算法原理 I.由题目我们知道需要返回将数组的所以数字组合......
  • 代码随想录算法训练营第二十五天|LeetCode491.递增子序列、46.全排列、47.全排列II、3
    前言打卡代码随想录算法训练营第49期第二十五天  ○(^皿^)っHiahiahia…首先十分推荐学算法的同学可以先了解一下代码随想录,可以在B站卡哥B站账号、代码随想录官方网站代码随想录了解,卡哥清晰易懂的算法教学让我直接果断关注,也十分有缘和第49期的训练营大家庭一起进步。今......
  • LeetCode题解:29.两数相除【Python题解超详细,位运算、二分查找法、递归法】,知识拓展:位
    题目描述        给你两个整数,被除数 dividend 和除数 divisor。将两数相除,要求 不使用 乘法、除法和取余运算。整数除法应该向零截断,也就是截去(truncate)其小数部分。例如,8.345 将被截断为 8 ,-2.7335 将被截断至 -2 。返回被除数 dividend 除以除数 div......
  • LeetCode:1207.独一无二的出现次数——Java哈希表
    目录1.题目如下: 2.题目解析:3.暴力解法:4.复杂度分析:1.题目如下: 给你一个整数数组 arr,如果每个数的出现次数都是独一无二的,就返回 true;否则返回 false。示例1:输入:arr=[1,2,2,1,1,3]输出:true解释:在该数组中,1出现了3次,2出现了2次,3只出现了1次。没......
  • 【滑动窗口】变种题目:leetcode76:最小覆盖子串
    前言滑动窗口是算法的数组部分中非常重要的一个内容,关于滑动窗口的题目,我已经发布过相关的变种题目文章,链接如下,欢迎访问:【滑动窗口】相关题目分析讲解:leetcode209,leetcode904如果你不了解什么是滑动窗口,推荐观看代码随想录的基础讲解视频:拿下滑动窗口!|LeetCode......
  • LeetCode---JZ85 连续子数组的最大和(二)
    示例代码importjava.util.*;publicclassSolution{publicint[]FindGreatestSumOfSubArray(int[]array){//记录到下标i为止的最大连续子数组和的最大值int[]dp=newint[array.length];dp[0]=array[0];intmaxsum=......
  • leetcode每日一题:3181.执行操作可获得的最大总奖励 II
     题干:读本文前,请先弄懂上一篇中的内容,因为这是对上一篇内容的优化:3180.执行操作可获得的最大总奖励I明白上篇的,访问值的影响、复制、上下行之间的关系和算法后可继续看:上一篇中,我们用二维数组,第二维表示了状态空间。但是,在今日的题目中,提交不行,因为占用的空间太太太......
  • LeetCode|384. 打乱数组(day22)
    作者:MJ昊博客:掘金、CSDN等公众号:程序猿的编程之路今天是昊的算法之路第22天,今天分享的是LeetCode第384题打乱数组的解题思路。这是一道中等难度的题目,要求我们实现一个算法,使得数组支持随机打乱和重置为初始顺序的功能,并且每种排列出现的概率应当相等。题目描述简要......
  • LeetCode_70. 爬楼梯_java
    1、题目70.爬楼梯https://leetcode.cn/problems/climbing-stairs/假设你正在爬楼梯。需要n阶你才能到达楼顶。每次你可以爬1或2个台阶。你有多少种不同的方法可以爬到楼顶呢?示例1:输入:n=2输出:2解释:有两种方法可以爬到楼顶。1.1阶+1阶2.2阶示例2:输......