JAVA - BFS with Sorted Trees - Clean with comments
\nclass Solution {\n    public int cutOffTree(List<List<Integer>> forest) {\n        \n        //1) put all tree\'s into a list\n        //2) sort the tree list
```\nclass Solution {\n    public int cutOffTree(List<List<Integer>> forest) {\n        \n        //1) put all tree\'s into a list\n        //2) sort the tree list by smallest\n        //3) from idx (0,0) cut down all the trees by getting the next smallest tree from the list\n        //4) call bfs to count the steps from current starting index until the next smallest tree\n        \n        //so if you can make it from the beginning to the smallest tree. count the steps at that tree as the new starting point to get to the next smallest\n        \n        List<int[]> trees = new ArrayList<>();\n        \n        int R = forest.size(), C = forest.get(0).size();\n        \n        //1)\n        for(int r = 0; r < R; r++){\n            \n            for(int c = 0; c < C; c++){\n                \n                int treeHeight = forest.get(r).get(c);\n                \n                if(treeHeight < 2) continue;\n                \n                trees.add(new int[]{ r, c, treeHeight});\n            }\n        }\n        \n        //2)\n        Collections.sort(trees, (tree1, tree2) -> { return tree1[2] - tree2[2]; });\n        \n        int steps = 0;\n        \n        //3)\n        int[] startTree = new int[] { 0, 0 };\n        \n        for(int[] nextTree : trees){\n            \n            int stepsToNextTree = getStepsToNextTree(forest, startTree, nextTree, R, C);\n            \n            //we could not make it to the next tree, therefore not all trees can be cut down\n            if(stepsToNextTree < 0) return -1;\n            \n            steps += stepsToNextTree;\n            \n            //the current next tree becomes the new start tree\n            \n            startTree = nextTree;\n        }\n        \n        return steps;\n    }\n    \n    private int[][] directions = new int[][]{ {0, 1}, {0, -1}, {-1, 0}, {1, 0} };\n    \n    private int getStepsToNextTree(List<List<Integer>> forest, int[] startTree, int[] nextTree, int R, int C){\n        \n        //implelent bfs to move around the board taking steps to reach the next tree\n        //do not move back to a visited tree within this function\n        boolean[][] seen = new boolean[R][C];\n        \n        seen[startTree[0]][startTree[1]] = true;\n        \n        Queue<int[]> toVisit = new LinkedList<>();\n\n        toVisit.offer(startTree);\n        \n        int steps = 0;\n        \n        while(!toVisit.isEmpty()){\n            \n            //pop elements off the q and process level by level\n            int size = toVisit.size();\n                \n            for(int i = 0; i < size; i++){\n                \n                int[] visitedTree = toVisit.poll();\n                \n                //if we have reached the next tree we can stop\n                if(visitedTree[0] == nextTree[0] && visitedTree[1] == nextTree[1]) return steps;\n\n                //search surrounding cells for a connection to the next tree\n                \n                for(int[] dir : directions){\n                    \n                    int r = visitedTree[0] + dir[0];\n                    int c = visitedTree[1] + dir[1];\n                    \n                    if(r < R && c < C && r >= 0 && c >= 0 && !seen[r][c] && forest.get(r).get(c) > 0){\n                        \n                        toVisit.offer(new int[]{r, c});\n                        seen[r][c] = true;\n                    }\n                }\n            }\n            \n            //each time we visit a tree, we find all surrounding connected trees - however we only move one step when we visit that tree\n            steps++;\n        }\n        \n        //if we have proccessed all surrounding cells as possible but not found the nextTree that means we will cannot connect to it\n        return -1;\n    }\n}\n```
[]