[LeetCode] 200. 岛屿数量

自己想的版本 

package leetcode;

/**
 * @author doyinana
 * @create 2020-04-20 23:20
 */
public class L200 {
    char[][] grid;
    public int numIslands(char[][] grid) {
        this.grid=grid;
        int m=grid.length;
        int n=grid[0].length;
        int count=0;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]==1){
                    count +=1;
                    color(grid,i,j);
                }
            }
        }
        return count;
    }

    public void color(char[][] grid,int i,int j){
        grid[i][j]=0;
        int[] x={-1,1,0,0};
        int[] y={0,0,1,-1};
        for(int o=0;o<4;o++){
            if(grid[i+1][j]==1){
                grid[i+x[o]][j+y[o]]=0;
                color(grid,i+x[o],j+y[o]);
            }
        }
    }
}
View Code

有错误,没有想到边界问题,还是可以另外建立一个单独的数组来存储是否访问过的

下面的和自己想到的方法一样 DFS

class Solution {
    private static final int[][] directions = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
        // 标记数组,标记了 grid 的坐标对应的格子是否被访问过
        private boolean[][] marked;
        // grid 的行数
        private int rows;
        // grid 的列数
        private int cols;
        private char[][] grid;

        public int numIslands(char[][] grid) {
            rows = grid.length;
            if (rows == 0) {
                return 0;
            }
            cols = grid[0].length;
            this.grid = grid;
            marked = new boolean[rows][cols];
            int count = 0;
            for (int i = 0; i < rows; i++) {
                for (int j = 0; j < cols; j++) {
                    // 如果是岛屿中的一个点,并且没有被访问过
                    // 就进行深度优先遍历
                    if (!marked[i][j] && grid[i][j] == '1') {
                        count++;
                        dfs(i, j);
                    }
                }
            }
            return count;
        }

        // 从坐标为 (i,j) 的点开始进行深度优先遍历
        private void dfs(int i, int j) {
            marked[i][j] = true;
            // 得到 4 个方向的坐标
            for (int k = 0; k < 4; k++) {
                int newX = i + directions[k][0];
                int newY = j + directions[k][1];
                // 如果不越界、没有被访问过、并且还要是陆地
                if (inArea(newX, newY) && grid[newX][newY] == '1' && !marked[newX][newY]) {
                    dfs(newX, newY);
                }
            }
        }

        // 封装成 inArea 方法语义更清晰
        private boolean inArea(int x, int y) {
            // 等于号不要忘了
            return x >= 0 && x < rows && y >= 0 && y < cols;
        }
}

这个和上面的方法一样啊,只是写的方式不一样了就快了这么多,厉害

class Solution {
    public int numIslands(char[][] grid) {
        if (grid.length == 0) return 0;
        boolean[][] visited = new boolean[grid.length][grid[0].length];
        int count = 0;
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[i].length; j++) {
                if (grid[i][j] == '1' && !visited[i][j]) {
                    count++;
                    visit(grid, i, j, visited);
                }
            }
        }
        return count;
    }
    
    private void visit(char[][] grid, int i, int j, boolean[][] visited) {
        if (i < 0 || j < 0 || i >= grid.length || j >= grid[i].length) return;
        if (visited[i][j]) return; 
        if (grid[i][j] =='0') return;
        visited[i][j] = true;
        visit(grid, i - 1, j, visited);
        visit(grid, i + 1, j, visited);
        visit(grid, i, j + 1, visited);
        visit(grid, i, j - 1, visited);

    }
}

posted @ 2020-04-20 23:56  doyi  阅读(155)  评论(0编辑  收藏  举报