1020. 飞地的数量

原题链接:

1020. 飞地的数量

https://editor.csdn.net/md/?not_checkout=1&spm=1000.2115.3001.5352

完成情况:

在这里插入图片描述

解题思路:

这段代码是一个使用深度优先搜索(DFS)算法来计算被围绕的区域数量的解决方案。该代码包含一个Solution类,其中定义了一个私有的dfs方法和一个公有的numEnclaves方法。

在dfs方法中,首先判断当前位置是否为0,如果是则返回;否则将当前位置标记为0,并增加计数器count。然后对当前位置的四个相邻位置进行遍历,如果相邻位置合法且为1,则递归调用dfs方法。

在numEnclaves方法中,首先对第一列和最后一列中为1的位置调用dfs方法,然后对第一行和最后一行中非边界位置为1的元素调用dfs方法。最后对内部位置为1的元素调用dfs方法,并返回计数器count的值。

整体思路是通过深度优先搜索算法遍历连通的陆地区域,将访问过的位置标记为0,最终统计被围绕的区域数量。

参考代码:

_1020飞地的数量__dfs

package 代码随想录.图论;

public class _1020飞地的数量__dfs {
    int count = 0;
    int dir [][] = {
            {0,1},
            {0,-1},
            {1,0},
            {-1,0}
    };
    /**
     * "1"试着往外走,并且能够走出边界,,或者说是走到海洋
     * @param grid
     * @return
     */
    public int numEnclaves(int[][] grid) {
        //避免后续的越界检查,因此前期先对边界进行一遍过滤
        for (int i = 0; i < grid.length; i++){
            if (grid[i][0] == 1){
                dfs_numEnclaves(grid,i,0);
            }
            if (grid[i][grid[0].length - 1] == 1){
                dfs_numEnclaves(grid,i,grid[0].length - 1);
            }
        }
        for (int j = 0;j< grid[0].length-1;j++){
            if (grid[0][j] == 1){
                dfs_numEnclaves(grid,0,j);
            }
            if (grid[grid.length-1][j] == 1){
                dfs_numEnclaves(grid, grid.length - 1, j);
            }
        }
        //初始化count
        count = 0;
        for (int i = 1; i < grid.length; i++){
            for (int j = 1;j< grid[0].length-1;j++){
                if (grid[i][j] == 1){
                    dfs_numEnclaves(grid,i,j);
                }
            }
        }
        return count;
    }

    /**
     *
     * @param grid
     * @param i
     * @param j
     */
    private void dfs_numEnclaves(int[][] grid, int i, int j) {
        //dfs向四个方便去遍历,主要针对需求进行改正,,,
        //遇到1进行连接,,,遇到0则可以结束了
        if (grid[i][j] == 0){
            return;
        }
        grid[i][j] = 0;
        count++;
        //老样子,走四个方向
        for (int way = 0; way < 4; way++) {
            int next_i = i + dir[way][0];
            int next_j = j + dir[way][1];
            if (next_i < 0 || next_j < 0 || next_i >= grid.length || next_j >= grid[0].length){
                continue;
            }
            dfs_numEnclaves(grid,next_i,next_j);
        }
    }
}

_1020飞地的数量__bfs

package 代码随想录.图论;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Queue;

public class _1020飞地的数量__bfs {
    int dir [][] = {
            {0,1},
            {0,-1},
            {1,0},
            {-1,0}
    };
    /**
     *
     * @param grid
     * @return
     */
    public int numEnclaves(int[][] grid) {
        int row = grid.length,col = grid[0].length,result = 0;
        //标记数组记录每个值为1的位置是否可以到达边界
        boolean [][] visited = new boolean[row][col];
        Deque<int []> queue = new ArrayDeque<int[]>();
        //搜索左侧边界和右侧边界,查找1,存入队列中
        //先遍历边界
        for (int r = 0;r < row;r++){
            if (grid[r][0] == 1){
                visited[r][0] = true;
                queue.add(new int[]{r,0});
            }
            if (grid[r][col-1] == 1){
                visited[r][col - 1] = true;
                queue.add(new int[]{r,col - 1});
            }
        }
        for (int c = 0;c < row;c++){
            if (grid[0][c] == 1){
                visited[0][c] = true;
                queue.add(new int[]{0,c});
            }
            if (grid[row-1][c] == 1){
                visited[row-1][c] = true;
                queue.add(new int[]{row-1,c});
            }
        }
        //---------------------------------------------
        //广度优先遍历
        bfs_numEnclaves(grid,queue,visited);    //广度优先遍历
        //查找没有标记过的1,记录到res中
        for (int r = 1;r < row;r++){
            for (int c = 1;c < col;c++){
                if (grid[r][c] == 1 && !visited[r][c]){
                    ++result;
                }
            }
        }
        return result;
    }

    /**
     *
     * @param grid
     * @param queue
     * @param visited
     */
    private void bfs_numEnclaves(int[][] grid, Deque<int[]> queue, boolean[][] visited) {
       while (!queue.isEmpty()){
           int [] curPos = queue.poll();
           for (int [] way : dir){
               int curRow = curPos[0] + way[0],curCol = curPos[1] + way[1];
               //检测是否会导致下标越界
               if (curRow < 0 || curCol < 0 || curRow > grid.length-1 || curCol > grid[0].length-1){
                   continue;
               }
               //当前位置不是1,,或者已经被访问了,就直接跳过
               if (visited[curRow][curCol] || grid[curRow][curCol] == 0)    continue;
               visited[curRow][curCol] = true;
               queue.add(new int[]{curRow, curCol});
           }
       }
    }
}

错误经验吸取

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值