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

  • 相关阅读:
    Spring使用Jackson处理json数据
    手工搭建web项目
    购物车模块
    C# ——利用反射动态加载dll
    C# —— 利用Marshal.GetDelegateForFunctionPointer 来转换一个函数指针为一个委托
    C# —— GetProcAddress函数检索指定的动态链接库(DLL)中的输出库函数地址。
    c#——IntPtr
    C#-StructLayoutAttribute(结构体布局)
    C#报错——传递数组对象报错“未将对象引用设置到对象的实例”
    C#——保留小数点,强转
  • 原文地址:https://www.cnblogs.com/panini/p/6850746.html
Copyright © 2011-2022 走看看