Algorithm-Island Problem Album

The island problem is basically an algorithm: deep search + memorized search.

1. Number of islands

  1. List item

200. Number of Islands

给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。

示例 1:

输入:
11110
11010
11000
00000

输出: 1
示例 2:

输入:
11000
11000
00100
00011

输出: 3

Problem-solving ideas: deep search + memory search.
The searched node is not searching, and the complexity is O(m*n)

    public int numIslands(char[][] grid) {
    
    
        int count=0;
        for(int i=0;i<grid.length;i++){
    
    
            for(int j=0;j<grid[0].length;j++){
    
    
                if(grid[i][j]=='1'){
    
    
                    dfs(grid,i,j);
                    count++;
                }
            }
        }
        return count;
    }

    public void dfs(char[][] matrix,int i,int j){
    
    
        if(i<0||j<0||i>=matrix.length||j>=matrix[0].length||matrix[i][j]!='1'){
    
    
            return;
        }
        matrix[i][j]='*';//上下左右搜一遍
        dfs(matrix,i-1,j);
        dfs(matrix,i+1,j);
        dfs(matrix,i,j-1);
        dfs(matrix,i,j+1);
    }

2. Surrounded area

130. Surrounded area

给定一个二维的矩阵,包含 'X' 和 'O'(字母 O)。

找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。

示例:

X X X X
X O O X
X X O X
X O X X
运行你的函数后,矩阵变为:

X X X X
X X X X
X X X X
X O X X
解释:

被围绕的区间不会存在于边界上,换句话说,任何边界上的 'O' 都不会被填充为 'X'。 任何不在边界上,或不与边界上的 'O' 相连的 'O' 最终都会被填充为 'X'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。

Problem-solving ideas:
1. Deep search for the positions of O on all boundaries, replace
2. Deep search for all Os and replace with X
3. Restore the data replaced in 1

     public void solve(char[][] board) {
    
    
        for (int i=0;i<board.length;i++){
    
    
            for (int j=0;j<board[0].length;j++){
    
    
                if(i==0||j==0||i==board.length-1||j==board[0].length-1){
    
    
                    dfs(board,i,j,'-','O');
                }
            }
        }
        for (int i=0;i<board.length;i++){
    
    
            for (int j=0;j<board[0].length;j++){
    
    
                dfs(board,i,j,'X','O');
            }
        }
        for (int i=0;i<board.length;i++){
    
    
            for (int j=0;j<board[0].length;j++){
    
    
                dfs(board,i,j,'O','-');
            }
        }
    }

    public void dfs(char[][] board,int i,int j,char replace,char target){
    
    
        if(i<0||j<0||i>=board.length||j>=board[0].length||board[i][j]!=target){
    
    
            return;
        }
        board[i][j]=replace;
        dfs(board,i+1,j,replace,target);
        dfs(board,i-1,j,replace,target);
        dfs(board,i,j+1,replace,target);
        dfs(board,i,j-1,replace,target);
    }

3. The largest area of ​​the island

695. The largest area of ​​the island

给定一个包含了一些 0 和 1 的非空二维数组 grid 。

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

找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为 0 。)

 

示例 1:

[[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:

[[0,0,0,0,0,0,0,0]]
对于上面这个给定的矩阵, 返回 0。

After the routines of the above two questions, it is relatively simple to solve this question.

You can record the area of ​​the island during deep search + memory search, and then select a maximum value

    public int maxAreaOfIsland(int[][] grid) {
    
    
        int maxArea=0;
        if(grid.length==0||grid[0].length==0){
    
    
            return 0;
        }
        for(int i=0;i<grid.length;i++){
    
    
            for(int j=0;j<grid[0].length;j++){
    
    
                if(grid[i][j]==1){
    
    
                    maxArea=Math.max(maxArea,dfs(grid,i,j));
                }
            }
        }
        return maxArea;
    }

    public int dfs(int[][] grid,int i,int j){
    
    
        if(i<0||j<0||i>=grid.length||j>=grid[0].length||grid[i][j]!=1){
    
    
            return 0;
        }
        grid[i][j]=2;
        return 1+ dfs(grid,i+1,j)+dfs(grid,i-1,j)+dfs(grid,i,j+1)+dfs(grid,i,j-1);

    }

4. Island circumference

463. Circumference of the Island

给定一个包含 0 和 1 的二维网格地图,其中 1 表示陆地 0 表示水域。

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

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

示例 :

输入:
[[0,1,0,0],
 [1,1,1,0],
 [0,1,0,0],
 [1,1,0,0]]

输出: 16

解释: 它的周长是下面图片中的 16 个黄色的边:

Insert picture description here

This question is actually very simple. Think about it. Each 1 contributes up to 4 side lengths. Once there is a 1 connected to it, its contribution side length is reduced by one. Based on this idea, every time we traverse to 1, we can see if its top, bottom, left, and right are 1, and if so, subtract 1.

    public int islandPerimeter(int[][] grid) {
    
    
        int count=0;
        for (int i=0;i<grid.length;i++){
    
    
            for (int j=0;j<grid[0].length;j++){
    
    
                if(grid[i][j]==1){
    
    
                    count+=4;
                    if(i>0&&grid[i-1][j]==1){
    
    //上面
                        count--;
                    }
                    if(i<grid.length-1&&grid[i+1][j]==1){
    
    //下面
                        count--;
                    }
                    if(j>0&&grid[i][j-1]==1){
    
    //左面
                        count--;
                    }
                    if(j<grid[0].length-1&&grid[i][j+1]==1){
    
    //右面
                        count--;
                    }
                }
            }
        }
        return  count;
    }

Guess you like

Origin blog.csdn.net/qq_23594799/article/details/105623073