Number of Islands Leetcode

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

图的第一道题。。。看了太阁的视频,代码写的晦涩难懂。。。然后看了下top solution,真的是有水平的。。。不过也许太阁的代码有普适性吧,并没有好好研究。。。

思想主要就是用DFS的方法,遇到一个点就把它相关的点都遍历,把1替换成0来标记自己遍历过了。其实很简单,看来自己之前的畏难心理重了。

public class Solution {
    private int m;
    private int n;
    public int numIslands(char[][] grid) {
        if (grid == null) {
            return 0;
        }
        m = grid.length;
        if (m == 0) {
            return 0;
        }
        int count = 0;
        n = grid[0].length;
        
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == '1') {
                    dfs(grid, i, j);
                    count++;
                }
            }
        }
        return count;
    }
    public void dfs(char[][] grid, int i, int j) {
        if (i < 0 || j < 0 || i >= m || j >= n || grid[i][j] != '1') {
            return;
        }
        grid[i][j] = '0';
        dfs(grid, i - 1, j);
        dfs(grid, i + 1, j);
        dfs(grid, i, j - 1);
        dfs(grid, i, j + 1);
    }
}

不过用DFS有stack over flow的风险,所以推荐用BFS或者union find, 今天把union find做啦,更新一下,bfs以后再写。。。到时候回顾一下。。。

union find:

public class Solution {
    public int numIslands(char[][] grid) {
        if (grid == null || grid.length == 0 || grid[0].length == 0) {
            return 0;
        }
        int m = grid.length;
        int n = grid[0].length;
        UF uf = new UF(grid, m, n);
        int count = 0;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == '1'){
                    count++;
                }
            }
        }
        uf.setCount(count);
        int[][] dir = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == '1'){
                    for (int[] cor : dir) {
                        int row = i + cor[0];
                        int col = j + cor[1];
                        if (row >=0 && row < m && col >= 0 && col < n && grid[row][col] == '1') {
                            uf.connect(i * n + j, row * n + col);
                        }
                    }
                    grid[i][j] = '0';
                }
            }
        }
        return uf.query();

    }
    class UF {
        int[] id = null;
        int count;
        public UF(char[][] grid, int m, int n) {
            id = new int[m * n];
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    id[i * n + j] = i * n + j;
                }
            }
        }
        public int find(int n) {
            if (id[n] == n) {
                return n;
            }
            id[n] = find(id[n]);
            return id[n];
        }
        public void connect(int a, int b) {
            int roota = find(a);
            int rootb = find(b);
            if (roota != rootb) {
                id[roota] = rootb;
                count--;
            }
        }
        public void setCount(int count) {
            this.count = count;
        }
        public int query() {
            return count;
        }
    }

}

学习这种东西啊,果然是躲得过初一躲不过十五的。。。今天乖乖来做BFS了。。。

bfs就是一层层遍历,把为1的点加到总数里面,然后用bfs把与这个1相邻的所有的点变成0,可以用queue。

写完了发现跑的比前两个慢很多,大概因为用了新的数据结构并且新建了类吧。

public class Solution {
    class Coordinate {
        int x;
        int y;
        public Coordinate (int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
    public int numIslands(char[][] grid) {
        if (grid == null || grid.length == 0 || grid[0].length == 0) {
            return 0;
        }
        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') {
                    bfs(grid, i, j);
                    count++;
                }
            }
        }
        return count;
    }
    public void bfs(char[][] grid, int x, int y) {
        int[] dx = {0, 1, -1, 0};
        int[] dy = {1, 0, 0, -1};
        Queue<Coordinate> q = new LinkedList<>();
        grid[x][y] = '0';
        q.offer(new Coordinate(x, y));
        while (!q.isEmpty()) {
            Coordinate tmp = q.poll();
            for (int i = 0; i < 4; i++) {
                Coordinate newC = new Coordinate(tmp.x + dx[i], tmp.y + dy[i]);
                if (inBound(grid, newC.x, newC.y) && grid[newC.x][newC.y] == '1') {
                    q.offer(newC);
                    grid[newC.x][newC.y] = '0';
                }
            }
        }
    }
    public boolean inBound(char[][] grid, int x, int y) {
        if (x < 0 || y < 0 || x >= grid.length || y >= grid[0].length) {
            return false;
        }
        return true;
    }
}

 

posted @ 2017-02-04 10:08  璨璨要好好学习  阅读(147)  评论(0编辑  收藏  举报