https://leetcode.cn/problems/cut-off-trees-for-golf-event/
class Solution {
//你需要按照树的高度从低向高砍掉所有的树
public int cutOffTree(List<List<Integer>> forest) {
ArrayList<int[]> trees=new ArrayList<>();
int m=forest.size();
int n=forest.get(0).size();
//将所有树加入集合
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(forest.get(i).get(j)>1){
trees.add(new int[]{i,j});
}
}
}
//将所有树按照高度排序
Collections.sort(trees,(a,b)->(forest.get(a[0]).get(a[1])-forest.get(b[0]).get(b[1])));
int cx=0;
int cy=0;
int res=0;
//从低到高遍历所有树,计算他们之间的距离
for(int i=0;i<trees.size();i++){
int steps=dfs(forest,cx,cy,trees.get(i)[0],trees.get(i)[1]);
if(steps==-1){
return -1;
}
res+=steps;
cx=trees.get(i)[0];
cy=trees.get(i)[1];
}
return res;
}
int[][] dir=new int[][]{{0,1},{0,-1},{1,0},{-1,0}};
public int dfs(List<List<Integer>> forest,int x,int y,int tx,int ty){
if(x==tx&&y==ty){
return 0;
}
int row=forest.size();
int col=forest.get(0).size();
Deque<int[]> deque=new ArrayDeque<>();
boolean[][] visited=new boolean[row][col];
deque.offer(new int[]{x,y});
visited[x][y]=true;
int step=0;
while(!deque.isEmpty()){
step++;
int size=deque.size();//保存这一层的大小
for(int j=0;j<size;j++){
int[] tmp=deque.poll();
for(int i=0;i<dir.length;i++){//试图向四个方向走
int nx=tmp[0]+dir[i][0];
int ny=tmp[1]+dir[i][1];
if(nx>=0&&ny>=0&&nx<row&&ny<col){//数组不越界
if(!visited[nx][ny]&&forest.get(nx).get(ny)>0){//可以行走
if(nx==tx&&ny==ty){//此时已到达目标,直接返回
return step;
}
else{
deque.offer(new int[]{nx,ny});
visited[nx][ny]=true;
}
}
}
}
}
}
return -1;
}
}