原题链接:
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;
}
}