zoukankan      html  css  js  c++  java
  • 200. Number of Islands

    题目:

    Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

    Example 1:

    11110
    11010
    11000
    00000

    Answer: 1

    Example 2:

    11000
    11000
    00100
    00011

    Answer: 3

    链接:https://leetcode.com/problems/number-of-islands/#/description

    5/13/2017

    4ms, 41%

    注意高亮的地方

    DFS做法

     1 public class Solution {
     2     boolean[][] visited;
     3     public int numIslands(char[][] grid) {
     4         if (grid == null) return 0;
     5         if (grid.length == 0 || grid[0].length == 0) return 0;
     6         int count = 0;
     7         visited = new boolean[grid.length][grid[0].length];
     8         
     9         for (int i = 0; i < grid.length; i++) {
    10             for (int j = 0; j < grid[0].length; j++) {
    11                 if (grid[i][j] == '1' && !visited[i][j]) {
    12                     countIslands(grid, i, j);
    13                     count++;
    14                 }
    15             }
    16         }
    17         return count;
    18     }
    19     
    20     private void countIslands(char[][] grid, int i, int j) {
    21         if (grid[i][j] != '1') return;
    22         if (visited[i][j]) {
    23             return;
    24         }
    25         visited[i][j] = true;
    26         if (i - 1 >= 0) countIslands(grid, i - 1, j);
    27         if (i + 1 <= grid.length - 1) countIslands(grid, i + 1, j);
    28         if (j - 1 >= 0) countIslands(grid, i, j - 1);
    29         if (j + 1 <= grid[0].length - 1) countIslands(grid, i, j + 1);
    30     }
    31 }

    BFS

    不想改变原来数组,错误做法,原因是set.contains不能按照equals来识别

    对Java不熟悉,set不是按照equals来判断吗?还是说这里用了HashSet来实现,所以必须实现hashCode才能正确的使用set.contains

    槽点太多,不改了

    *更新,代码没有更新,但是加了一点research结果。简单来说,如果要用hashset, hashmap用于自定义的类的时候,在必要情况下,必须同时自定义equals(), hashCode()

    对于本题来说,2个不同的点的instance可以是不一样的objcet,所以hashCode不一样,然而我们的应用是只要坐标一样就可以,所以要按照坐标来实现hashCode

    http://stackoverflow.com/questions/3692426/hashset-does-not-seem-to-realize-that-two-objects-are-the-same

    http://stackoverflow.com/questions/17801611/implementing-hashcode-and-equals-for-custom-classes

    错误做法,不work

     1 public class Solution {
     2     class Point {
     3         int x;
     4         int y;
     5         public Point(int x, int y) {
     6             this.x = x;
     7             this.y = y;
     8         }
     9         public boolean equals(Object p) {
    10             if (!(p instanceof Point))
    11                 return false;
    12             Point point = (Point)p;
    13             return this.x == point.x && this.y == point.y;
    14         }
    15     }
    16     public int numIslands(char[][] grid) {
    17         if (grid == null) return 0;
    18         if (grid.length == 0 || grid[0].length == 0) return 0;
    19         int count = 0;
    20         Queue<Point> queue = new LinkedList<Point>();
    21         Set<Point> set = new HashSet<Point>();
    22 
    23         for (int i = 0; i < grid.length; i++) {
    24             for (int j = 0; j < grid[0].length; j++) {
    25                 Point current = new Point(i, j);
    26                 if (grid[i][j] == '1' && !set.contains(current)) {
    27                     queue.add(current);
    28                     set.add(current);
    29                     while (!queue.isEmpty()) {
    30                         Point p = queue.poll();
    31                         if (grid[p.x][p.y] != '1' || set.contains(p)) continue;
    32                         set.add(p);
    33                         if (p.x + 1 < grid.length) {
    34                             Point t = new Point(p.x + 1, p.y);
    35                             queue.add(t);
    36                         }
    37                         if (p.x - 1 >= 0) {
    38                             Point t = new Point(p.x - 1, p.y);
    39                             queue.add(t);
    40                         }
    41                         if (p.y + 1 < grid[0].length) {
    42                             Point t = new Point(p.x, p.y + 1);
    43                             queue.add(t);
    44                         }
    45                         if (p.y - 1 >= 0) {
    46                             Point t = new Point(p.x, p.y - 1);
    47                             queue.add(t);
    48                         }                        
    49                     }
    50                     count++;
    51                 }
    52             }
    53         }
    54         return count;
    55     }
    56 }

    正确做法

    注意的问题,把周边的方格统统加入,poll出来的时候再判断会少了4条分支分别判断的麻烦,第24行

    第21行之后不要把visited置1,否则跟第24行冲突了

     1 public class Solution {
     2     class Point {
     3         int x;
     4         int y;
     5         public Point(int x, int y) {
     6             this.x = x;
     7             this.y = y;
     8         }
     9     }
    10     public int numIslands(char[][] grid) {
    11         if (grid == null) return 0;
    12         if (grid.length == 0 || grid[0].length == 0) return 0;
    13         int count = 0;
    14         Queue<Point> queue = new LinkedList<Point>();
    15         boolean[][] visited = new boolean[grid.length][grid[0].length];
    16 
    17         for (int i = 0; i < grid.length; i++) {
    18             for (int j = 0; j < grid[0].length; j++) {
    19                 Point current = new Point(i, j);
    20                 if (grid[i][j] == '1' && !visited[i][j]) {
    21                     queue.add(current);
    22                     while (!queue.isEmpty()) {
    23                         Point p = queue.poll();
    24                         if (grid[p.x][p.y] != '1' || visited[p.x][p.y]) continue;
    25                         visited[p.x][p.y] = true;
    26                         if (p.x + 1 < grid.length) {
    27                             Point t = new Point(p.x + 1, p.y);
    28                             queue.add(t);
    29                         }
    30                         if (p.x - 1 >= 0) {
    31                             Point t = new Point(p.x - 1, p.y);
    32                             queue.add(t);
    33                         }
    34                         if (p.y + 1 < grid[0].length) {
    35                             Point t = new Point(p.x, p.y + 1);
    36                             queue.add(t);
    37                         }
    38                         if (p.y - 1 >= 0) {
    39                             Point t = new Point(p.x, p.y - 1);
    40                             queue.add(t);
    41                         }                        
    42                     }
    43                     count++;
    44                 }
    45             }
    46         }
    47         return count;
    48     }
    49 }

    BFS的好处就是不会导致stackoverflow,在一个函数中就可以搞定了。DFS有溢出的风险。BFS,DFS本身与用不用visited无关。

    别人有将grid在判断之后置1的,count and sink,不过我个人不喜欢更改输入

    更多讨论

    https://discuss.leetcode.com/category/208/number-of-islands

  • 相关阅读:
    Android studio 安装,JDK 出错解决方案
    Struts2 一、 视图转发跳转
    @Transactional 注解说明
    基于Schema的AOP 配置使用详解
    CSS滤镜让图片模糊(毛玻璃效果)实例页面
    Struts 2.3.4.1完整示例
    StudentSchema student实例数据库环境搭建
    network is unreachable 解决方案之一
    Oracle 转换函数
    Oracle检查与安装操作内容
  • 原文地址:https://www.cnblogs.com/panini/p/6850746.html
Copyright © 2011-2022 走看看