一文解决LeetCode岛屿问题

岛屿问题一

题目链接

463. 岛屿的周长

题目描述

解题思路

求岛屿的周长其实有很多种方法,如果用 DFS 遍历来求的话,有一种很简单的思路:岛屿的周长就是岛屿方格和非岛屿方格相邻的边的数量。注意,这里的非岛屿方格,既包括水域方格,也包括网格的边界。我们可以画一张图,看得更清晰:

AC代码

class Solution {
    int ans = 0;
    int dir[][] = {{0,1},{0,-1},{-1,0},{1,0}};
    public void dfs(int[][] grid,int[][] used,int x,int y){
        if(x < 0 || x >= grid.length || y < 0 || y >= grid[0].length){
            ans++;
            return;
        }
        if(grid[x][y] == 0){
            ans++;
            return;
        }
        if(used[x][y] == 1) return;
        used[x][y]=1;
        for(int i = 0; i < 4; i++){
            int xx = x + dir[i][0];
            int yy = y + dir[i][1];
            dfs(grid,used,xx,yy);
        }
    }


    public int islandPerimeter(int[][] grid) {
        int xLen = grid.length;
        int yLen = grid[0].length;
        int[][] used = new int[xLen][yLen];
        for(int i = 0; i < xLen; i++){
            for(int j = 0; j < yLen; j++){
                if(grid[i][j] == 1){
                    dfs(grid,used,i,j);
                    break;
                }
            }
        }
        return ans;
    }
}

岛屿问题二

题目链接

200. 岛屿数量

题目描述

解题思路

之前很困惑,一直不理解返回值为非void类型的递归函数如何编写,因为返回值为void的情况,直接传入全局变量即可,不需要去考虑局部变量的值。经过这些岛屿问题,总算是明白了函数的参数以及函数内的局部变量是每个函数栈独有的,但递归函数回退到之前某个函数栈时,对应的局部变量的值也就回退到之前的版本,然后全局变量的好处就在于它的不会随着递归函数的回退而改变。

AC代码

class Solution {
    int dir[][] = {{0,1},{0,-1},{1,0},{-1,0}};
    int ans = 0;
    public int dfs(char[][] grid,int used[][],int x,int y){
        if(x < 0 || x >= grid.length || y < 0 || y>= grid[0].length) return 0;
        if(grid[x][y] == '0') return 0;
        //对于返回值为int递归函数而言,该语句很关键,就不需要写if(grid[x][y]==1){}这种类型的代码块。
        if(used[x][y] == 1) return 0;
        used[x][y] = 1;
        for(int i = 0; i < 4; i++){
            int xx = x + dir[i][0];
            int yy = y + dir[i][1];
            int num = dfs(grid,used,xx,yy);
        }
        return 1;
    }

    public int numIslands(char[][] grid) {
        int[][] used = new int[grid.length][grid[0].length];
        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,used,i,j);
                }
            }
        }
        return ans;
    }
}

岛屿问题三

题目链接

695. 岛屿的最大面积

题目描述

解题思路

同样本题也在于编写返回值为int类型的递归函数,注意本题的两个解法:尤其是累加局部变量的解法。

AC代码

解法一:累加局部变量

class Solution {
    int dir[][] = {{0,1},{0,-1},{-1,0},{1,0}};
    public int dfs(int[][] grid,int[][] used,int x,int y){
        if(x < 0 || x >= grid.length || y < 0 || y>=grid[0].length) return 0;
        if(grid[x][y] == 0) return 0;
        if(used[x][y] == 1) return 0;
        used[x][y] = 1;
        int cnt = 1;
        for(int i = 0; i < 4; i++){
            int xx = x + dir[i][0];
            int yy = y + dir[i][1];
            cnt += dfs(grid,used,xx,yy);
        }
        return cnt;
    }
    public int maxAreaOfIsland(int[][] grid) {
        int ans = 0;
        int used[][] = new int[grid.length][grid[0].length];
        for(int i = 0; i < grid.length; i++){
            for(int j = 0; j < grid[0].length; j++){
                if(grid[i][j] == 1){
                    ans = Math.max(ans,dfs(grid,used,i,j));
                }
            }
        }
        return ans;
    }
}

解法二:使用全局变量

class Solution {
    int dir[][] = {{0,1},{0,-1},{-1,0},{1,0}};
    int cnt = 0;
    public int dfs(int[][] grid,int[][] used,int x,int y){
        if(x < 0 || x >= grid.length || y < 0 || y>=grid[0].length) return 0;
        if(grid[x][y] == 0) return 0;
        if(used[x][y] == 1) return 0;
        if(grid[x][y] == 1) cnt++;
        used[x][y] = 1;
        for(int i = 0; i < 4; i++){
            int xx = x + dir[i][0];
            int yy = y + dir[i][1];
            int nm = dfs(grid,used,xx,yy);
        }
        return cnt;
    }
    public int maxAreaOfIsland(int[][] grid) {
        int ans = 0;
        int used[][] = new int[grid.length][grid[0].length];
        for(int i = 0; i < grid.length; i++){
            for(int j = 0; j < grid[0].length; j++){
                if(grid[i][j] == 1){
                    ans = Math.max(ans,dfs(grid,used,i,j));
                    cnt = 0;
                }
            }
        }
        return ans;
    }
}
posted @ 2020-10-30 10:50  控球强迫症  阅读(308)  评论(0编辑  收藏  举报