1020. 飞地的数量

原题链接:

1020. 飞地的数量

https://leetcode.cn/problems/number-of-enclaves/description/

完成情况:

在这里插入图片描述

解题思路:

private final static int [][] directions = {{-1,0},{1,0},{0,-1},{0,1}};
private int rows,columns; //减少递归函数中,额外的参数调用
private boolean [][] visited;

/**
*

  • @param grid
  • @return
    */
    … for (int i = 1;i<rows-1;i++){
    for (int j = 1;j<columns-1;j++){
    if (grid[i][j] == 1 && !visited[i][j]){
    enclaves++;
    }
    }
    }
    return enclaves;
    }“”

这段代码定义了一个二维数组 directions,存储了四个方向的偏移量;声明了 rows 和 columns 变量,用来减少递归函数中的额外参数调用;还定义了一个二维布尔数组 visited。

在主要的代码逻辑中,通过两个 for 循环遍历二维数组 grid,当 grid[i][j] 的值为 1 且 visited[i][j] 为 false 时,将 enclaves 的值加一。最终返回 enclaves 的值。

参考代码:

_1020飞地的数量_dfs_定义方向

package leetcode板块;

public class _1020飞地的数量_dfs_定义方向 {
    private final static int [][] directions = {{-1,0},{1,0},{0,-1},{0,1}};
    private int rows,columns;   //减少递归函数中,额外的参数调用
    private boolean [][] visited;

    /**
     *
     * @param grid
     * @return
     */
    public int numEnclaves(int[][] grid) {
        rows = grid.length;
        columns = grid[0].length;
        visited = new boolean[rows][columns];
        //----------先处理四个边界---------------------------
        for (int i = 0; i < rows; i++){
            dfs_numEnclaves(grid,i,0);
            dfs_numEnclaves(grid,i,columns-1);
        }
        for (int j = 1;j<columns;j++){
            dfs_numEnclaves(grid,0,j);
            dfs_numEnclaves(grid,rows-1,j);
        }
        //--------对中间值逐个去dfs,寻找满足条件的飞地enclaves---------
        int enclaves = 0;
        for (int i = 1;i<rows - 1;i++){
            for (int j = 1;j<columns - 1;j++){
                if (grid[i][j] == 1 && !visited[i][j]){     //如果满足为1,且已经访问过这个节点,那么它就是飞地enclaves
                    enclaves++;
                }
            }
        }
        return enclaves;
    }

    /**
     *
     * @param grid
     * @param curRow
     * @param curCol
     */
    private void dfs_numEnclaves(int[][] grid, int curRow, int curCol) {
        //边界判断
        if (curRow < 0 || curRow >= rows || curCol < 0 || curCol >= columns || grid[curRow][curCol] == 0 || visited[curRow][curCol]){
            return ;
        }
        //节点为1
        visited[curRow][curCol] = true;
        //遍历它的四个方向
        for (int [] dir :directions){
            dfs_numEnclaves(grid,curRow + dir[0],curCol+dir[1]);
        }
    }
}

_1020飞地的数量_bfs_定义方向

package leetcode板块;

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

public class _1020飞地的数量_bfs_定义方向 {
    private final static int [][] directions = {{-1,0},{1,0},{0,-1},{0,1}};
    private int rows,columns;   //减少递归函数中,额外的参数调用
    private boolean [][] visited;

    /**
     *
     * @param grid
     * @return
     */
    public int numEnclaves(int[][] grid) {
        rows = grid.length;
        columns = grid[0].length;
        visited = new boolean[rows][columns];
        //bfs就不需要额外调用了,使用队列来解决
        Deque<int []> myQueue = new ArrayDeque<>();     //用于判断四个方向,所以采用int []
        //----------先处理四个边界---------------------------
        for (int i = 0; i < rows; i++){
            if (grid[i][0] == 1){
                visited[i][0] = true;
                myQueue.offer(new int[]{i,0});
            }
            if (grid[i][columns - 1] == 1){
                visited[i][columns - 1] = true;
                myQueue.offer(new int[]{i,columns-1});
            }
        }
        for (int j = 1;j<columns;j++){
            if (grid[0][j] == 1){
                visited[0][j] = true;
                myQueue.offer(new int[]{0,j});
            }
            if (grid[rows-1][j] == 1){
                visited[rows-1][j] = true;
                myQueue.offer(new int[]{rows-1,j});
            }
        }
        //-------------对队列中每一个元素进行四个方向的遍历查询----------------------
        while (!myQueue.isEmpty()){
            int [] queueCell  = myQueue.poll();
            int curRow = queueCell[0],curCol = queueCell[1];
            for (int [] dir : directions){
                int nextRow = curRow + dir[0],nextCol = curCol + dir[1];
                if (nextRow >= 0 && nextRow < rows && nextCol >= 0 && nextCol < columns && grid[nextRow][nextCol] == 1 && !visited[nextRow][nextCol]){
                    visited[nextRow][nextCol] = true;
                    myQueue.offer(new int[]{nextRow,nextCol});
                }
            }
        }
        int enclaves = 0;
        for (int i = 1;i<rows-1;i++){
            for (int j = 1;j<columns-1;j++){
                if (grid[i][j] == 1 && !visited[i][j]){
                    enclaves++;
                }
            }
        }
        return enclaves;
    }

}

错误经验吸取

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值