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

posted @ 2017-05-13 22:52  panini  阅读(242)  评论(0编辑  收藏  举报