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