岛屿问题(岛数量/孤岛/面积/周长)

Posted yangbocsu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了岛屿问题(岛数量/孤岛/面积/周长)相关的知识,希望对你有一定的参考价值。

岛屿问题

200. 岛屿数量

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

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

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

参考代码

class Solution 
    public int numIslands(char[][] grid) 
        int ans = 0;
        int m = grid.length;
        int n = grid[0].length;

        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++)
                if(grid[i][j] =='1')
                    ans ++;
                    dfs(grid,i,j);
                
            
        
        return ans;
    

    void dfs(char[][] grid, int i, int j)
        int m = grid.length;
        int n = grid[0].length;
        if(i < 0 || i >= m || j < 0 || j>=n)
            // 超出边界
            return;
        
        
        if(grid[i][j] !='1')
            return ;// 已经是海水了
        

        grid[i][j] = '2'; // 将 (i, j) 变成海水
        // 淹没上下左右的陆地
        dfs(grid,i+1,j);
        dfs(grid,i-1,j);
        dfs(grid,i,j+1);
        dfs(grid,i,j-1);
    

1254. 统计封闭岛屿的数目

二维矩阵 grid 由 0 (土地)和 1 (水)组成。岛是由最大的4个方向连通的 0 组成的群,封闭岛是一个 完全 由1包围(左、上、右、下)的岛。

请返回 封闭岛屿 的数目。

输入:grid = [
[1,1,1,1,1,1,1,0],
[1,0,0,0,0,1,1,0],
[1,0,1,0,1,1,1,0],
[1,0,0,0,0,1,0,1],
[1,1,1,1,1,1,1,0]]
输出:2
解释:
灰色区域的岛屿是封闭岛屿,因为这座岛屿完全被水域包围(即被 1 区域包围)。

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

参考代码

class Solution 
    public int closedIsland(int[][] grid) 
        int m = grid.length;
        int n = grid[0].length;

        // 将左边界和右边界 淹没
        for(int i = 0; i < m; i++)
            dfs(grid,i,0);    // 把靠左边的岛屿淹掉
            dfs(grid,i,n-1);  // 把靠下边的岛屿淹掉
        

        // 将上边界和下边界烟波
        for(int j = 0; j < n; j++)
            dfs(grid,0,j);   // 把靠上边的岛屿淹掉
            dfs(grid,m-1,j); // 把靠下边的岛屿淹掉
        
        int ans = 0;
        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++)
                    if(grid[i][j] == 0)
                        ans ++;
                        dfs(grid,i,j); 
                    
            
        
        return ans;
    

    public void dfs(int[][] grid,int i,int j)
        if(i < 0 || i >= grid.length || j<0 || j>=grid[0].length)
            return;
        
        // 已经是海水了
        if(grid[i][j] == 1)
            return ;
        
        //将 (i, j) 变成海水
        grid[i][j] = 1;

        dfs(grid,i,j-1);
        dfs(grid,i,j+1);
        dfs(grid,i-1,j);
        dfs(grid,i+1,j);
    

本题与岛屿数量的区别在于 边界上的岛屿不算岛屿,因为题目要求统计封闭岛屿的数目,这点注意了,代码就出来了。

class Solution 
    int val = 0;
    public int closedIsland(int[][] grid) 
        int m = grid.length;
        int n = grid[0].length;

        // // 将左边界和右边界 淹没
        // for(int i = 0; i < m; i++)
        //     dfs(grid,i,0);    // 把靠左边的岛屿淹掉
        //     dfs(grid,i,n-1);  // 把靠下边的岛屿淹掉
        // 

        // // 将上边界和下边界烟波
        // for(int j = 0; j < n; j++)
        //     dfs(grid,0,j);   // 把靠上边的岛屿淹掉
        //     dfs(grid,m-1,j); // 把靠下边的岛屿淹掉
        // 

        int ans = 0;
        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++)
                    if(grid[i][j] == 0)
                        val = 1;
                        dfs(grid,i,j); 
                        ans += val;
                    
            
        
        return ans;
    

    public void dfs(int[][] grid,int i,int j)
        if(i < 0 || i >= grid.length || j<0 || j>=grid[0].length)
            val = 0;
            return;
        
        // 已经是海水了
        if(grid[i][j] == 1)
            return ;
        
        //将 (i, j) 变成海水
        grid[i][j] = 1;

        dfs(grid,i,j-1);
        dfs(grid,i,j+1);
        dfs(grid,i-1,j);
        dfs(grid,i+1,j);
    

695. 岛屿的最大面积

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

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

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

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

输入: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

参考代码

class Solution 
    public int maxAreaOfIsland(int[][] grid) 
        int ans = 0;
        for(int i = 0; i < grid.length; i++)
            for(int j = 0 ; j < grid[0].length; j++)
                if(grid[i][j] == 1)
                    int tempArea = area(grid,i,j);
                    ans = Math.max(ans,tempArea);
                
            
        
        return ans;
    

    public int area(int[][] grid, int i ,int j)
        // 数组下标到边界到,再走就要越界了。
        if( i<0 || i>=grid.length || j<0 || j>=grid[0].length )
            return 0;   
            // 关于|| 和 && 的说明,你是越界,越界的话,有多种可能,只要其中一种满足就可以了。
            // && 是必须在四个边界之内    
        

        // 如果遇到的不是岛屿,也直接返回
        if(grid[i][j] != 1)
            return 0;
        

        // 到这里,这格就是岛屿了 grid[i][j] == 1
        grid[i][j] = 2;  // 但是,我要加面积,你给我把这格变为2了,所以下面就是 1 +

        return 1 
                + area(grid,i,j-1)
                + area(grid,i,j+1)
                + area(grid,i+1,j)
                + area(grid,i-1,j);

    

    // 判断坐标 (r, c) 是否在网格中
    public boolean inArea(int[][] grid, int i, int j) 
        return i>=0 && i < grid.length && j>=0 && j < grid[0].length;
    




463. 岛屿的周长

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

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

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

参考代码

class Solution 
    public int islandPerimeter(int[][] grid) 
        int ans= 0;
        first:for(int i = 0; i < grid.length; i++)
            for(int j = 0; j < grid[0].length; j++)
                if(grid[i][j] == 1)
                    ans = dfs(grid,i,j);
                    break first;
                
            
        
        return ans;
    

    public int dfs(int[][] grid, int i ,int j)
        // 遇到边界时,就是一边的长
        if( i<0 || i >= grid.length || j<0 || j>=grid[0].length)
            return 1;
        

        // 遇到海洋 grid[i][j] == 0 也算是要一边的长
        if(grid[i][j] == 0)
            return 1;
        

        //
        if(grid[i][j] == 2)
            return 0;
        

        grid[i][j] = 2;

        return dfs(grid,i,j-1) + dfs(grid,i,j+1) 岛屿问题(岛数量/孤岛/面积/周长)

51nod 1276 岛屿的数量

[Offer收割]编程练习赛11 题目3 : 岛屿3

200. 岛屿数量(Python)

51nod 1276 1276 岛屿的数量 (很好玩的题目

岛屿类问题的通用解法DFS 遍历框架