class Solution {
static int[]dx={0,0,1,-1};
static int[]dy={1,-1,0,0};
//1.确定砍树顺序
public static int cutOffTree(List<List<Integer>> f){
int m=f.size(),n=f.get(0).size();
List<int[]>trees=new ArrayList<>();
for(int i=0;i<m;i++) {
for (int j = 0; j < n; j++) {
if (f.get(i).get(j) > 1) {
//把需要砍的树都放到这个容器里面
trees.add(new int[]{i, j});
}
}
}
//容器的排序,需要去书写比较器
Collections.sort(trees,(a,b)->{
return f.get(a[0]).get(a[1])-f.get(b[0]).get(b[1]);
});
//按照顺序砍树
int ret=0;
int bx=0,by=0;
for(int[]tree:trees){
//bx为当前坐标位置
int x=tree[0],y=tree[1];
//ex,ey为终点的坐标,也就是xy,trees是需要砍的树
int step=bfs(f,bx,by,x,y);
if(step==-1){
return -1;
}
ret+=step;
bx=x;
by=y;
}
return ret;
}
//常规的迷宫
public static int bfs(List<List<Integer>>f,int bx,int by,int ex,int ey) {
if (bx == ex && by == ey) return 0;
Queue<int[]> q = new LinkedList<>();
int m = f.size(), n = f.get(0).size();
boolean[][] vis = new boolean[m][n];
//标记当前值
q.add(new int[]{bx, by});
//初始化标记
vis[bx][by] = true;
int step = 0;
while (!q.isEmpty()) {
step++;
int sz = q.size();
//和上次一样,size是为了看
while (sz != 0) {
int[] t = q.poll();
//出当前队列
int a = t[0], b = t[1];
for (int i = 0; i < 4; i++) {
int x = a + dx[i], y = b + dy[i];
//下标是否合法
if (x >= 0 && y >= 0 && x < m && y < n && f.get(x).get(y) != 0 && vis[x][y] == false) {
//如果到达了位置,就可以直接返回step
if (x == ex && y == ey) return step;
q.add(new int[]{x, y});
vis[x][y] = true;
}
}
sz--;
}
}
return -1;
}
}
class Solution {
static int[] dx = {0, 0, 1, -1};
static int[] dy = {1, -1, 0, 0};
public static int numEnclaves(int[][] grid) {
int m = grid.length, n = grid[0].length;
int count = 0;
Queue<int[]> q = new LinkedList<>();
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++) {
if ((i == 0 || i == m - 1 || j == 0 || j == n - 1) && grid[i][j] == 1) {
//边界上的1我们不去算他,只去保存他的下标就好
grid[i][j]=100;
q.add(new int[]{i, j});
}
}
while (!q.isEmpty()) {
int sz = q.size();
while (sz != 0) {
int[] t = q.poll();
int a = t[0], b = t[1];
for (int i = 0; i < 4; i++) {
int x = a + dx[i], y = b + dy[i];
//检查这里面的假如是1,那么就说明我们能从边界到达,换句话说,他能够出去,那么我们就给他设置成-1,假如遍历不到的,那么就不去改变他
if (x >= 0 && y >= 0 && x < m && y < n && grid[x][y] == 1) {
q.add(new int[]{x, y});
grid[x][y] = -1;
}
}
sz--;
}
}
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++) {
//只去遍历我们从边界到达不到的地方。
if (grid[i][j] == 1)
count++;
}
return count;
}
}