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;
    }
}