LC1020:飞地的数量

题目

给你一个大小为 m x n 的二进制矩阵 grid ,其中 0 表示一个海洋单元格、1 表示一个陆地单元格。

一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 grid 的边界。

返回网格中 无法 在任意次数的移动中离开网格边界的陆地单元格的数量。

示例 1:

输入: grid = [[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]]
输出: 3
解释: 有三个 1 被 0 包围。一个 1 没有被包围,因为它在边界上。

解法

我自己是用的bfs,速度还行,击败了82.73%的Java用户

image.png

我自己写的如下:

class Solution {
    boolean[][] st;
    int n, m, count;
    int[] dx= {0, 0, 1, -1}, dy= {1, -1, 0 , 0};
    class pair {
        int x, y;
        public pair(int x, int y) {
            this.x = x;this.y = y;
        }
    }
    public int numEnclaves(int[][] grid) {
        n = grid.length;
        m = grid[0].length;
        st = new boolean[n + 1][m + 1];
        int count = 0;
        for(int i = 0;i < n;i ++) {
            if(grid[i][0] == 1 && !st[i][0]) {
                find(i, 0, grid);
            }
        }
        for(int i = 0;i < n;i ++) {
            if(grid[i][m - 1] == 1 && !st[i][m - 1]) {
                find(i, m - 1, grid);
            }
        }
        for(int i = 0;i < m;i ++) {
            if(grid[0][i] == 1 && !st[0][i]) {
                find(0, i, grid);
            }
        }
        for(int i = 0;i < m;i ++) {
            if(grid[n - 1][i] == 1 && !st[n - 1][i]) {
                find(n - 1, i, grid);
            }
        }
        for(int i = 1;i < n - 1;i ++) {
            for(int j = 1;j < m - 1;j ++) {
                if(grid[i][j] == 1 && !st[i][j]) {
                    count ++;
                }
            }
        }
        return count;

    }
    public void find(int x, int y, int[][] grid) {
        ArrayDeque<pair> aq = new ArrayDeque<>();
        aq.offer(new pair(x, y));
        st[x][y] = true;
        while(!aq.isEmpty()) {
            pair p = aq.poll();
            for(int i =0 ;i < 4;i ++) {
                int nx = p.x + dx[i], ny = p.y + dy[i];
                if(nx < 0 || ny < 0 || nx >= n || ny >= m || grid[nx][ny] == 0) continue;
                if(!st[nx][ny]) {
                    st[nx][ny] = true;
                    aq.offer(new pair(nx, ny));
                }
                
            }
        }
    }
}   

看的速度更快的用dfs进行迭代的代码,很漂亮,值得学习

class Solution {
    public int numEnclaves(int[][] grid) {
        int res = 0;

        int n = grid.length, m = grid[0].length;

        for(int i = 0; i < n; i++){
            if(grid[i][0] == 1){
                dfs(grid, i, 0);
            }
        }

        for(int i = 0; i < n; i++){
            if(grid[i][m - 1] == 1){
                dfs(grid, i, m - 1);
            }
        }

        for(int j = 0; j < m; j++){
            if(grid[0][j] == 1){
                dfs(grid, 0, j);
            }
        }

        for(int j = 0; j < m; j++){
            if(grid[n - 1][j] == 1){
                dfs(grid, n - 1, j);
            }
        }

        for(int i = 1; i < n - 1; i++){
            for(int j = 1; j < m - 1; j++){
                if(grid[i][j] == 1){
                    res += 1;
                }
            }
        }

        return res;
    }

    void dfs(int[][] grid, int x, int y){
        if(!(0 <= x && x < grid.length && 0 <= y && y < grid[0].length)){
            return ;
        }

        if(grid[x][y] != 1){
            return;
        }

        grid[x][y] = 2;
        
        dfs(grid, x - 1, y);
        dfs(grid, x + 1, y);
        dfs(grid, x, y - 1);
        dfs(grid, x, y + 1);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值