关于岛屿的三道leetcode原题:岛屿周长、岛屿数量、统计子岛屿

这篇具有很好参考价值的文章主要介绍了关于岛屿的三道leetcode原题:岛屿周长、岛屿数量、统计子岛屿。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题1:岛屿周长

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

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

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

示例:

关于岛屿的三道leetcode原题:岛屿周长、岛屿数量、统计子岛屿,leetcode,算法,职场和发展,数据结构,c++

思路:

        一块土地原则上会带来4个周长,但岛上的土地存在接壤,会减掉2个边长。

所以,总周长=4*土地个数-2*接壤边的条数

遍历矩阵,遍历到土地,就land++,如果它的右边或下边也是土地,则border++,便遍历结束后代入公式即可。

关于岛屿的三道leetcode原题:岛屿周长、岛屿数量、统计子岛屿,leetcode,算法,职场和发展,数据结构,c++

 Code:

int islandPerimeter(int** grid, int gridSize, int* gridColSize){
    int land=0;//土地的块数
    int broader=0;//土地接壤的块数
    for(int i=0;i<gridSize;i++)
    {
        for(int j=0;j<gridColSize[i];j++)
        {
            if(grid[i][j])
            {
                land++;//如果遍历到土地,那么就land++
                if(i<gridSize-1&&grid[i+1][j])//如果土地的下方也是土地,那么broader++
                {
                    broader++;
                }
                if(j<gridColSize[i]-1&&grid[i][j+1])//如果土地的右方也是土地,那么broader++
                {
                    broader++;
                }
            }
        }
    }
    int result=4*land-2*broader;//一块土地有四条边,一个土地每接壤了一块土地,就要少两条边
    //所以总边数=4*土地块数-2*接壤土地块数
    return result;
}

题2:岛屿数量

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

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

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

示例1:

输入:grid = [
  ["1","1","1","1","0"],
  ["1","1","0","1","0"],
  ["1","1","0","0","0"],
  ["0","0","0","0","0"]
]
输出:1

示例2:

输入:grid = [
  ["1","1","0","0","0"],
  ["1","1","0","0","0"],
  ["0","0","1","0","0"],
  ["0","0","0","1","1"]
]
输出:3

思路:

        本题我们可以采用递归算法来实现,遍历矩阵,找到陆地后,开始递归查找当前位置的上下左右四个方向是否也为陆地。在这过程中要注意的是,每访问一块陆地后要将其更新为'0',防止重复访问,产生死循环。

Code:文章来源地址https://www.toymoban.com/news/detail-693316.html

class Solution {
public:
    void dfs(vector<vector<char>>& grid,int i,int j)
    {
        int n=grid.size();
        int m=grid[0].size();
        //访问过就更新为'0'
        grid[i][j]='0';
        //继续判断上下左右四个方向是否是岛屿
        if(i-1>=0 && grid[i-1][j]=='1') dfs(grid,i-1,j);
        if(i+1<n  && grid[i+1][j]=='1') dfs(grid,i+1,j);
        if(j-1>=0 && grid[i][j-1]=='1') dfs(grid,i,j-1);
        if(j+1<m  && grid[i][j+1]=='1') dfs(grid,i,j+1);
    }
    int numIslands(vector<vector<char>>& grid) {
        int n=grid.size();
        int m=grid[0].size();
        int num=0;//记录岛屿个数
        //遍历矩阵
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                //如果当前位置为陆地,也就是为'1',则找它的上下左右相连的陆地
                if(grid[i][j]=='1')
                {
                    dfs(grid,i,j);
                    //岛屿数量加1
                    num++;
                }
            }
        }
        return num;
    }
};

 题3:统计子岛屿

你两个 m x n 的二进制矩阵 grid1grid2 ,它们只包含 0 (表示水域)和 1 (表示陆地)。一个 岛屿 是由 四个方向 (水平或者竖直)上相邻的 1 组成的区域。任何矩阵以外的区域都视为水域。

如果 grid2 的一个岛屿,被 grid1 的一个岛屿 完全 包含,也就是说 grid2 中该岛屿的每一个格子都被 grid1 中同一个岛屿完全包含,那么我们称 grid2 中的这个岛屿为 子岛屿

请你返回 grid2子岛屿数目

示例:

关于岛屿的三道leetcode原题:岛屿周长、岛屿数量、统计子岛屿,leetcode,算法,职场和发展,数据结构,c++

输入:grid1 = [[1,1,1,0,0],[0,1,1,1,1],[0,0,0,0,0],[1,0,0,0,0],[1,1,0,1,1]], grid2 = [[1,1,1,0,0],[0,0,1,1,1],[0,1,0,0,0],[1,0,1,1,0],[0,1,0,1,0]]
输出:3
解释:如上图所示,左边为 grid1 ,右边为 grid2 。
grid2 中标红的 1 区域是子岛屿,总共有 3 个子岛屿。

思路:

1.首先要明确子岛屿的定义:grid2 的一个岛屿必须grid1 的一个岛屿 完全 包含。

2.我们采用递归算法来实现本题

3.在写递归条件时,我们需要考虑的是,当遇到下标越界或是土地2的一个岛屿已经结束(也就是grid2[i][j]!=1)时,说明当前的这个子岛屿已经判断完毕,return true

4.每访问一个位置,就要将当前位置变成不是陆地,这里我设置成2,为了防止出现死循环,设置过之后,访问过的位置不会再次被访问

5.设置一个标记,用来标记当前是否为子岛屿

6.每次都要判断上下左右四个方向是否是陆地,且满足被包含在土地1的岛屿中

Code:

class Solution {
public:
    //坐标的偏移量(上下左右四个方向)
    int dx[4]={0,0,-1,1};
    int dy[4]={-1,1,0,0}; 
    bool dfs(vector<vector<int>>& grid1, vector<vector<int>>& grid2,int i,int j)
    {
        int n=grid1.size();
        int m=grid1[0].size();
        //如果不是陆地,或越界,返回true
        if(i>=n||i<0||j>=m||j<0||grid2[i][j]!=1) return true;
        //访问过的位置置为2,防止出现死循环
        grid2[i][j]=2;
        //设置标记flag,初始为true
        bool flag=true;
        //如果土地1当前位置不是陆地,则将flag置为flase,在最后统一返回,不能现在直接return,不然会导致有些岛屿没有判断到
        if(grid1[i][j]==0) flag=false;
        //开始找上下左右四个方向
        for(int k=0;k<4;k++)
        {
            int x=i+dx[k],y=j+dy[k];
            //这里flag必须两个条件相与,如果上一轮flag为false,那么说明土地1的岛屿没有完全包含土地2的岛屿,即使此时两块土地的位置都为1,也不符合题意,flag仍然为false
            flag=dfs(grid1,grid2,x,y) && flag;
        }
        return flag;
    }
        
    int countSubIslands(vector<vector<int>>& grid1, vector<vector<int>>& grid2) {
        int n=grid1.size();
        int m=grid1[0].size();
        int res=0;//记录子岛屿的个数
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                //如果当前土地2的位置是陆地,同时土地1的位置也是陆地,才能进入递归
                //因为我们在递归中,设置为只要不是陆地,那么当前位置就是子岛屿,所以进入递归的前提条件就是当前位置必须是陆地
                if(grid2[i][j]==1 && grid1[i][j]==1)
                {
                    if(dfs(grid1,grid2,i,j))
                        res++;
                }
            }
        }
        return res;
    }
};

到了这里,关于关于岛屿的三道leetcode原题:岛屿周长、岛屿数量、统计子岛屿的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • LeetCode-200. 岛屿数量【深度优先搜索 广度优先搜索 并查集 数组 矩阵】

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

    2024年04月14日
    浏览(33)
  • 代码随想录图论 第五天| 841.钥匙和房间 463. 岛屿的周长

    代码随想录图论 第五天| 841.钥匙和房间 一、 841.钥匙和房间 题目链接:https://leetcode.cn/problems/keys-and-rooms/ 思路:钥匙就是索引,遍历过就标记,每拿到一个房间的钥匙,直接for循环递归遍历,深度优先直接拿下。 二、463. 岛屿的周长 题目链接:https://leetcode.cn/problems/island-

    2024年02月06日
    浏览(40)
  • 图论第二天|岛屿数量.深搜版、岛屿数量.广搜版、岛屿的最大面积、1020.飞地的数量

    文档讲解 :代码随想录 - 岛屿数量.深搜版 状态:开始学习。 本题是dfs模板题 本题代码: 文档讲解 :代码随想录 - 岛屿数量.广搜版 状态:开始学习。 思路:bfs模板题 本题代码: 文档讲解 :代码随想录 - 岛屿的最大面积 状态:开始学习。 思路: 这道题目也是 dfs bfs 基础

    2024年02月08日
    浏览(34)
  • 力扣200. 岛屿数量

    思路: 假设在 (r, c) 格子位置,r 为所处行,c 为所处的列; 遇到陆地格子之后,遍历搜索其上下左右周围的陆地格子,但是不能超出边界,即对应的数组下标不越界; 为了避免重复多次搜索,搜索到陆地格子之后将其标记染色; 四周搜索完所有的陆地格子,即为一个岛屿;

    2024年02月04日
    浏览(38)
  • 16.3:岛屿数量问题2

    https://leetcode.cn/problems/number-of-islands-ii/ 给你一个大小为 m x n 的二进制网格 grid 。网格表示一个地图,其中, 0 表示水, 1 表示陆地。最初, grid 中的所有单元格都是水单元格(即,所有单元格都是 0 )。 可以通过执行 addLand 操作,将某个位置的水转换成陆地。给你一个数组

    2024年02月07日
    浏览(29)
  • 岛屿数量 -- 二维矩阵的dfs算法

    岛屿数量 又被称为 FloodFill 算法

    2024年02月09日
    浏览(34)
  • C++面试宝典第20题:计算岛屿数量

    题目         在二维网格地图上,\\\'1\\\' 表示陆地,\\\'0\\\' 表示水域。如果相邻的陆地可以水平或垂直连接,则它们属于同一块岛屿。请进行编码,统计地图上的岛屿数量。比如:下面的二维网格地图,其岛屿数量为3。 解析         这道题主要考察应聘者对深度优先搜索、

    2024年01月18日
    浏览(29)
  • 力扣真题:200. 岛屿数量(两种实现方法)

     java代码实现: 用了类似感染的方法,就是一个节点出发,如果此时这个节点没被感染,且是陆地,就可以进入遍历,将其邻接的陆地全部遍历一遍,标志数组sign相应位置至为1.然后一次遍历一块陆地,能遍历几次就代表有几块陆地。 这种方法相较于第一种有了不错的优化

    2024年02月14日
    浏览(40)
  • 代码随想录图论 第一天 | 797.所有可能的路径 200. 岛屿数量

    代码随想录图论 第一天 | 797.所有可能的路径 200. 岛屿数量 一、797.所有可能的路径 题目链接:https://leetcode.cn/problems/all-paths-from-source-to-target/ 思路:求从0到n-1的所有路径,终止条件是当前节点为n-1。本题图的结构是group[][],group[x]表示x节点所能到达的所有节点的集合,深度

    2024年02月08日
    浏览(48)
  • 代码随想录图论 第二天 | 695. 岛屿的最大面积 1020. 飞地的数量

    代码随想录图论 第二天 | 695. 岛屿的最大面积 1020. 飞地的数量 一、695. 岛屿的最大面积 题目链接:https://leetcode.cn/problems/max-area-of-island/ 思路:典型的遍历模板题,我采用深度优先,每块岛屿递归遍历的时候计数,递归完比较大小记录最大值。 二、1020. 飞地的数量 题目链接

    2024年02月07日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包