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;
    }
}

 

转载于:https://www.cnblogs.com/aprilyang/p/6364098.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值