zoukankan      html  css  js  c++  java
  • [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);
    
        }
    }

  • 相关阅读:
    装饰器模块和面试题
    装饰器和推导式
    设计商城系统,主要提供两个功能:商品管理、会员管理。
    写代码:三级菜单
    写代码:循环打印names列表,把元素和索引值都打印出来。
    写代码: 编写登录接口
    写代码:假设一年期定期利率为3.25%,计算一下需要过多少年,一万元的一年定期存款连本带息能翻番?
    写代码:输入一年份,判断该年份是否是闰年并输出结果。
    写代码:制作趣味模板程序
    变量n1和n2是什么关系
  • 原文地址:https://www.cnblogs.com/doyi111/p/12741631.html
Copyright © 2011-2022 走看看