READABLE CODE with FUNCTIONS/COMMENTS ~ Python Solution BFS with Priority Queue
This code is written in a way that should be understandable by most Leetcoders :)\nI\'d recommend reading it in the following order:\nminStepsToCell, getPossibl
This code is written in a way that should be understandable by most Leetcoders :)\nI\'d recommend reading it in the following order:\nminStepsToCell, getPossibleMoves (standard bfs)\ncreateTreeLocationsPriorityQueue,getNextTreeLocation (priority queue / function to feed us the next tree location)\ncutOffTree -> logic that combines the two concepts (bfs + priority queue)\n\n```\nclass Solution:\n    def cutOffTree(self, forest: List[List[int]]) -> int:\n        self.createTreeLocationsPriorityQueue(forest)\n        steps = 0\n        treeLoc = self.getNextTreeLocation()\n        currLoc = (0,0)\n        while treeLoc != -1: \n\t\t#if there are no more trees in the pq this means that we\'ve cut down all the trees and should return the sum of the steps taken\n\t\t#so in every loop we "cut" the next tree (move to the location of the next tree), if we can\'t we return -1 as per the problem statement.\n\t\t\n            costToTree = self.minStepsToCell(forest,currLoc,treeLoc)\n            if costToTree == -1:\n                return -1\n            steps += costToTree\n            currLoc = treeLoc\n            treeLoc = self.getNextTreeLocation()\n        return steps\n            \n    def getNextTreeLocation(self):\n\t#simply pops the next tree from the tree priority queue and returns its location\n        if self.treePQ:\n            height,i,j = heapq.heappop(self.treePQ)\n            return (i,j)\n        return -1\n    \n    def createTreeLocationsPriorityQueue(self,forest):\n\t#puts trees in a priority queue with the following format (treeheight,i,j)\n\t#when removing trees from the pq they will be removed shortest first,\n\t#this helps us easily get the location of the next tree to cut down.\n        self.treePQ = []\n        \n        for i in range(len(forest)):\n            for j in range(len(forest[0])):\n                if forest[i][j] > 1:\n                    heapq.heappush(self.treePQ,(forest[i][j],i,j))\n    \n    def minStepsToCell(self,forest,currLoc,targetLoc):\n\t#just a regular BFS to find the minimum distance from one location to another.\n\t#if we can\'t reach our destination we return -1\n        explored = set()\n        q = [currLoc]\n        steps = 0\n        while q:\n            nlq = []\n            \n            for loc in q:\n                if loc == targetLoc:\n                    return steps\n                if loc not in explored:\n                    explored.add(loc)\n                    nlq.extend(self.getPossibleMoves(forest,loc))\n                    \n            steps += 1\n            q = nlq\n        return -1\n            \n    def getPossibleMoves(self,forest,loc):\n\t#Simply get possible moves (can move to cells that are not \'0\'\n        i,j = loc\n        moves = []\n        if i > 0 and forest[i-1][j]:\n            moves.append((i-1,j))\n        if i < len(forest)-1 and forest[i+1][j]:\n            moves.append((i+1,j))\n        if j > 0 and forest[i][j-1]:\n            moves.append((i,j-1))\n        if j < len(forest[0])-1 and forest[i][j+1]:\n            moves.append((i,j+1))\n        return moves\n```
['Breadth-First Search', 'Heap (Priority Queue)', 'Python']